VendorTagDescriptor.cpp revision e1445da74730473a66a3ae8414e940aebfe6585d
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "VenderTagDescriptor"
18
19#include <binder/Parcel.h>
20#include <utils/Errors.h>
21#include <utils/Log.h>
22#include <utils/Mutex.h>
23#include <utils/Vector.h>
24#include <system/camera_metadata.h>
25#include <camera_metadata_hidden.h>
26
27#include "camera/VendorTagDescriptor.h"
28
29#include <string.h>
30
31namespace android {
32
33extern "C" {
34
35static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
36static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
37static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
38static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
39static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
40
41} /* extern "C" */
42
43
44static Mutex sLock;
45static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
46
47VendorTagDescriptor::VendorTagDescriptor() {}
48VendorTagDescriptor::~VendorTagDescriptor() {}
49
50status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
51            /*out*/
52            sp<VendorTagDescriptor>& descriptor) {
53    if (vOps == NULL) {
54        ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
55        return BAD_VALUE;
56    }
57
58    int tagCount = vOps->get_tag_count(vOps);
59    if (tagCount < 0 || tagCount > INT32_MAX) {
60        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
61        return BAD_VALUE;
62    }
63
64    Vector<uint32_t> tagArray;
65    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
66            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
67
68    vOps->get_all_tags(vOps, /*out*/tagArray.editArray());
69
70    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
71    desc->mTagCount = tagCount;
72
73    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
74        uint32_t tag = tagArray[i];
75        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
76            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
77            return BAD_VALUE;
78        }
79        const char *tagName = vOps->get_tag_name(vOps, tag);
80        if (tagName == NULL) {
81            ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
82            return BAD_VALUE;
83        }
84        desc->mTagToNameMap.add(tag, String8(tagName));
85        const char *sectionName = vOps->get_section_name(vOps, tag);
86        if (sectionName == NULL) {
87            ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
88            return BAD_VALUE;
89        }
90        desc->mTagToSectionMap.add(tag, String8(sectionName));
91        int tagType = vOps->get_tag_type(vOps, tag);
92        if (tagType < 0 || tagType >= NUM_TYPES) {
93            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
94            return BAD_VALUE;
95        }
96        desc->mTagToTypeMap.add(tag, tagType);
97    }
98    descriptor = desc;
99    return OK;
100}
101
102status_t VendorTagDescriptor::createFromParcel(const Parcel* parcel,
103            /*out*/
104            sp<VendorTagDescriptor>& descriptor) {
105    status_t res = OK;
106    if (parcel == NULL) {
107        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
108        return BAD_VALUE;
109    }
110
111    int32_t tagCount = 0;
112    if ((res = parcel->readInt32(&tagCount)) != OK) {
113        ALOGE("%s: could not read tag count from parcel", __FUNCTION__);
114        return res;
115    }
116
117    if (tagCount < 0 || tagCount > INT32_MAX) {
118        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
119        return BAD_VALUE;
120    }
121
122    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
123    desc->mTagCount = tagCount;
124
125    uint32_t tag;
126    int32_t tagType;
127    for (int32_t i = 0; i < tagCount; ++i) {
128        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&tag))) != OK) {
129            ALOGE("%s: could not read tag id from parcel for index %d", __FUNCTION__, i);
130            break;
131        }
132        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
133            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
134            res = BAD_VALUE;
135            break;
136        }
137        if ((res = parcel->readInt32(&tagType)) != OK) {
138            ALOGE("%s: could not read tag type from parcel for tag %d", __FUNCTION__, tag);
139            break;
140        }
141        if (tagType < 0 || tagType >= NUM_TYPES) {
142            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
143            res = BAD_VALUE;
144            break;
145        }
146        String8 tagName = parcel->readString8();
147        if (tagName.isEmpty()) {
148            ALOGE("%s: parcel tag name was NULL for tag %d.", __FUNCTION__, tag);
149            res = NOT_ENOUGH_DATA;
150            break;
151        }
152        String8 sectionName = parcel->readString8();
153        if (sectionName.isEmpty()) {
154            ALOGE("%s: parcel section name was NULL for tag %d.", __FUNCTION__, tag);
155            res = NOT_ENOUGH_DATA;
156            break;
157        }
158
159        desc->mTagToNameMap.add(tag, tagName);
160        desc->mTagToSectionMap.add(tag, sectionName);
161        desc->mTagToTypeMap.add(tag, tagType);
162    }
163
164    if (res != OK) {
165        return res;
166    }
167
168    descriptor = desc;
169    return res;
170}
171
172int VendorTagDescriptor::getTagCount() const {
173    size_t size = mTagToNameMap.size();
174    if (size == 0) {
175        return VENDOR_TAG_COUNT_ERR;
176    }
177    return size;
178}
179
180void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
181    size_t size = mTagToNameMap.size();
182    for (size_t i = 0; i < size; ++i) {
183        tagArray[i] = mTagToNameMap.keyAt(i);
184    }
185}
186
187const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
188    ssize_t index = mTagToSectionMap.indexOfKey(tag);
189    if (index < 0) {
190        return VENDOR_SECTION_NAME_ERR;
191    }
192    return mTagToSectionMap.valueAt(index).string();
193}
194
195const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
196    ssize_t index = mTagToNameMap.indexOfKey(tag);
197    if (index < 0) {
198        return VENDOR_TAG_NAME_ERR;
199    }
200    return mTagToNameMap.valueAt(index).string();
201}
202
203int VendorTagDescriptor::getTagType(uint32_t tag) const {
204    ssize_t index = mTagToNameMap.indexOfKey(tag);
205    if (index < 0) {
206        return VENDOR_TAG_TYPE_ERR;
207    }
208    return mTagToTypeMap.valueFor(tag);
209}
210
211status_t VendorTagDescriptor::writeToParcel(Parcel* parcel) const {
212    status_t res = OK;
213    if (parcel == NULL) {
214        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
215        return BAD_VALUE;
216    }
217
218    if ((res = parcel->writeInt32(mTagCount)) != OK) {
219        return res;
220    }
221
222    size_t size = mTagToNameMap.size();
223    uint32_t tag;
224    int32_t tagType;
225    for (size_t i = 0; i < size; ++i) {
226        tag = mTagToNameMap.keyAt(i);
227        String8 tagName = mTagToNameMap[i];
228        String8 sectionName = mTagToSectionMap.valueFor(tag);
229        tagType = mTagToTypeMap.valueFor(tag);
230        if ((res = parcel->writeInt32(tag)) != OK) break;
231        if ((res = parcel->writeInt32(tagType)) != OK) break;
232        if ((res = parcel->writeString8(tagName)) != OK) break;
233        if ((res = parcel->writeString8(sectionName)) != OK) break;
234    }
235
236    return res;
237}
238
239status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
240    status_t res = OK;
241    Mutex::Autolock al(sLock);
242    sGlobalVendorTagDescriptor = desc;
243
244    vendor_tag_ops_t* opsPtr = NULL;
245    if (desc != NULL) {
246        opsPtr = &(desc->mVendorOps);
247        opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
248        opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
249        opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
250        opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
251        opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
252    }
253    if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
254        ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)."
255                , __FUNCTION__, strerror(-res), res);
256    }
257    return res;
258}
259
260void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
261    Mutex::Autolock al(sLock);
262    set_camera_metadata_vendor_ops(NULL);
263    sGlobalVendorTagDescriptor.clear();
264}
265
266sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
267    Mutex::Autolock al(sLock);
268    return sGlobalVendorTagDescriptor;
269}
270
271extern "C" {
272
273int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v) {
274    Mutex::Autolock al(sLock);
275    if (sGlobalVendorTagDescriptor == NULL) {
276        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
277        return VENDOR_TAG_COUNT_ERR;
278    }
279    return sGlobalVendorTagDescriptor->getTagCount();
280}
281
282void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray) {
283    Mutex::Autolock al(sLock);
284    if (sGlobalVendorTagDescriptor == NULL) {
285        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
286        return;
287    }
288    sGlobalVendorTagDescriptor->getTagArray(tagArray);
289}
290
291const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag) {
292    Mutex::Autolock al(sLock);
293    if (sGlobalVendorTagDescriptor == NULL) {
294        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
295        return VENDOR_SECTION_NAME_ERR;
296    }
297    return sGlobalVendorTagDescriptor->getSectionName(tag);
298}
299
300const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag) {
301    Mutex::Autolock al(sLock);
302    if (sGlobalVendorTagDescriptor == NULL) {
303        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
304        return VENDOR_TAG_NAME_ERR;
305    }
306    return sGlobalVendorTagDescriptor->getTagName(tag);
307}
308
309int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag) {
310    Mutex::Autolock al(sLock);
311    if (sGlobalVendorTagDescriptor == NULL) {
312        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
313        return VENDOR_TAG_TYPE_ERR;
314    }
315    return sGlobalVendorTagDescriptor->getTagType(tag);
316}
317
318} /* extern "C" */
319} /* namespace android */
320