OSDN Git Service

Merge changes from topic "b23270724" into lmp-dev am: 5802bad0f4 am: 49acc79a1d ...
[android-x86/frameworks-av.git] / camera / VendorTagDescriptor.cpp
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 "VendorTagDescriptor"
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 <utils/SortedVector.h>
25 #include <system/camera_metadata.h>
26 #include <camera_metadata_hidden.h>
27
28 #include "camera/VendorTagDescriptor.h"
29
30 #include <stdio.h>
31 #include <string.h>
32
33 namespace android {
34
35 extern "C" {
36
37 static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
38 static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
39 static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
40 static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
41 static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
42
43 } /* extern "C" */
44
45
46 static Mutex sLock;
47 static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
48
49 namespace hardware {
50 namespace camera2 {
51 namespace params {
52
53 VendorTagDescriptor::~VendorTagDescriptor() {
54     size_t len = mReverseMapping.size();
55     for (size_t i = 0; i < len; ++i)  {
56         delete mReverseMapping[i];
57     }
58 }
59
60 VendorTagDescriptor::VendorTagDescriptor() :
61         mTagCount(0),
62         mVendorOps() {
63 }
64
65 VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
66     copyFrom(src);
67 }
68
69 VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
70     copyFrom(rhs);
71     return *this;
72 }
73
74 void VendorTagDescriptor::copyFrom(const VendorTagDescriptor& src) {
75     if (this == &src) return;
76
77     size_t len = mReverseMapping.size();
78     for (size_t i = 0; i < len; ++i) {
79         delete mReverseMapping[i];
80     }
81     mReverseMapping.clear();
82
83     len = src.mReverseMapping.size();
84     // Have to copy KeyedVectors inside mReverseMapping
85     for (size_t i = 0; i < len; ++i) {
86         KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
87         *nameMapper = *(src.mReverseMapping.valueAt(i));
88         mReverseMapping.add(src.mReverseMapping.keyAt(i), nameMapper);
89     }
90     // Everything else is simple
91     mTagToNameMap = src.mTagToNameMap;
92     mTagToSectionMap = src.mTagToSectionMap;
93     mTagToTypeMap = src.mTagToTypeMap;
94     mSections = src.mSections;
95     mTagCount = src.mTagCount;
96     mVendorOps = src.mVendorOps;
97 }
98
99 status_t VendorTagDescriptor::readFromParcel(const Parcel* parcel) {
100     status_t res = OK;
101     if (parcel == NULL) {
102         ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
103         return BAD_VALUE;
104     }
105
106     int32_t tagCount = 0;
107     if ((res = parcel->readInt32(&tagCount)) != OK) {
108         ALOGE("%s: could not read tag count from parcel", __FUNCTION__);
109         return res;
110     }
111
112     if (tagCount < 0 || tagCount > INT32_MAX) {
113         ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
114         return BAD_VALUE;
115     }
116
117     mTagCount = tagCount;
118
119     uint32_t tag, sectionIndex;
120     uint32_t maxSectionIndex = 0;
121     int32_t tagType;
122     Vector<uint32_t> allTags;
123     for (int32_t i = 0; i < tagCount; ++i) {
124         if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&tag))) != OK) {
125             ALOGE("%s: could not read tag id from parcel for index %d", __FUNCTION__, i);
126             break;
127         }
128         if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
129             ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
130             res = BAD_VALUE;
131             break;
132         }
133         if ((res = parcel->readInt32(&tagType)) != OK) {
134             ALOGE("%s: could not read tag type from parcel for tag %d", __FUNCTION__, tag);
135             break;
136         }
137         if (tagType < 0 || tagType >= NUM_TYPES) {
138             ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
139             res = BAD_VALUE;
140             break;
141         }
142         String8 tagName = parcel->readString8();
143         if (tagName.isEmpty()) {
144             ALOGE("%s: parcel tag name was NULL for tag %d.", __FUNCTION__, tag);
145             res = NOT_ENOUGH_DATA;
146             break;
147         }
148
149         if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&sectionIndex))) != OK) {
150             ALOGE("%s: could not read section index for tag %d.", __FUNCTION__, tag);
151             break;
152         }
153
154         maxSectionIndex = (maxSectionIndex >= sectionIndex) ? maxSectionIndex : sectionIndex;
155
156         allTags.add(tag);
157         mTagToNameMap.add(tag, tagName);
158         mTagToSectionMap.add(tag, sectionIndex);
159         mTagToTypeMap.add(tag, tagType);
160     }
161
162     if (res != OK) {
163         return res;
164     }
165
166     size_t sectionCount = 0;
167     if (tagCount > 0) {
168         if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&sectionCount))) != OK) {
169             ALOGE("%s: could not read section count for.", __FUNCTION__);
170             return res;
171         }
172         if (sectionCount < (maxSectionIndex + 1)) {
173             ALOGE("%s: Incorrect number of sections defined, received %zu, needs %d.",
174                     __FUNCTION__, sectionCount, (maxSectionIndex + 1));
175             return BAD_VALUE;
176         }
177         LOG_ALWAYS_FATAL_IF(mSections.setCapacity(sectionCount) <= 0,
178                 "Vector capacity must be positive");
179         for (size_t i = 0; i < sectionCount; ++i) {
180             String8 sectionName = parcel->readString8();
181             if (sectionName.isEmpty()) {
182                 ALOGE("%s: parcel section name was NULL for section %zu.",
183                       __FUNCTION__, i);
184                 return NOT_ENOUGH_DATA;
185             }
186             mSections.add(sectionName);
187         }
188     }
189
190     LOG_ALWAYS_FATAL_IF(static_cast<size_t>(tagCount) != allTags.size(),
191                         "tagCount must be the same as allTags size");
192     // Set up reverse mapping
193     for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
194         uint32_t tag = allTags[i];
195         String8 sectionString = mSections[mTagToSectionMap.valueFor(tag)];
196
197         ssize_t reverseIndex = -1;
198         if ((reverseIndex = mReverseMapping.indexOfKey(sectionString)) < 0) {
199             KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
200             reverseIndex = mReverseMapping.add(sectionString, nameMapper);
201         }
202         mReverseMapping[reverseIndex]->add(mTagToNameMap.valueFor(tag), tag);
203     }
204
205     return res;
206 }
207
208 int VendorTagDescriptor::getTagCount() const {
209     size_t size = mTagToNameMap.size();
210     if (size == 0) {
211         return VENDOR_TAG_COUNT_ERR;
212     }
213     return size;
214 }
215
216 void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
217     size_t size = mTagToNameMap.size();
218     for (size_t i = 0; i < size; ++i) {
219         tagArray[i] = mTagToNameMap.keyAt(i);
220     }
221 }
222
223 const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
224     ssize_t index = mTagToSectionMap.indexOfKey(tag);
225     if (index < 0) {
226         return VENDOR_SECTION_NAME_ERR;
227     }
228     return mSections[mTagToSectionMap.valueAt(index)].string();
229 }
230
231 const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
232     ssize_t index = mTagToNameMap.indexOfKey(tag);
233     if (index < 0) {
234         return VENDOR_TAG_NAME_ERR;
235     }
236     return mTagToNameMap.valueAt(index).string();
237 }
238
239 int VendorTagDescriptor::getTagType(uint32_t tag) const {
240     ssize_t index = mTagToNameMap.indexOfKey(tag);
241     if (index < 0) {
242         return VENDOR_TAG_TYPE_ERR;
243     }
244     return mTagToTypeMap.valueFor(tag);
245 }
246
247 status_t VendorTagDescriptor::writeToParcel(Parcel* parcel) const {
248     status_t res = OK;
249     if (parcel == NULL) {
250         ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
251         return BAD_VALUE;
252     }
253
254     if ((res = parcel->writeInt32(mTagCount)) != OK) {
255         return res;
256     }
257
258     size_t size = mTagToNameMap.size();
259     uint32_t tag, sectionIndex;
260     int32_t tagType;
261     for (size_t i = 0; i < size; ++i) {
262         tag = mTagToNameMap.keyAt(i);
263         String8 tagName = mTagToNameMap[i];
264         sectionIndex = mTagToSectionMap.valueFor(tag);
265         tagType = mTagToTypeMap.valueFor(tag);
266         if ((res = parcel->writeInt32(tag)) != OK) break;
267         if ((res = parcel->writeInt32(tagType)) != OK) break;
268         if ((res = parcel->writeString8(tagName)) != OK) break;
269         if ((res = parcel->writeInt32(sectionIndex)) != OK) break;
270     }
271
272     size_t numSections = mSections.size();
273     if (numSections > 0) {
274         if ((res = parcel->writeInt32(numSections)) != OK) return res;
275         for (size_t i = 0; i < numSections; ++i) {
276             if ((res = parcel->writeString8(mSections[i])) != OK) return res;
277         }
278     }
279
280     return res;
281 }
282
283 SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const {
284     return mSections;
285 }
286
287 status_t VendorTagDescriptor::lookupTag(String8 name, String8 section, /*out*/uint32_t* tag) const {
288     ssize_t index = mReverseMapping.indexOfKey(section);
289     if (index < 0) {
290         ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string());
291         return BAD_VALUE;
292     }
293
294     ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
295     if (nameIndex < 0) {
296         ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string());
297         return BAD_VALUE;
298     }
299
300     if (tag != NULL) {
301         *tag = mReverseMapping[index]->valueAt(nameIndex);
302     }
303     return OK;
304 }
305
306 void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
307
308     size_t size = mTagToNameMap.size();
309     if (size == 0) {
310         dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
311                 indentation, "");
312         return;
313     }
314
315     dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
316             indentation, "", size);
317     for (size_t i = 0; i < size; ++i) {
318         uint32_t tag =  mTagToNameMap.keyAt(i);
319
320         if (verbosity < 1) {
321             dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
322             continue;
323         }
324         String8 name = mTagToNameMap.valueAt(i);
325         uint32_t sectionId = mTagToSectionMap.valueFor(tag);
326         String8 sectionName = mSections[sectionId];
327         int type = mTagToTypeMap.valueFor(tag);
328         const char* typeName = (type >= 0 && type < NUM_TYPES) ?
329                 camera_metadata_type_names[type] : "UNKNOWN";
330         dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
331             "", tag, name.string(), type, typeName, sectionName.string());
332     }
333
334 }
335
336 } // namespace params
337 } // namespace camera2
338 } // namespace hardware
339
340
341 status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
342             /*out*/
343             sp<VendorTagDescriptor>& descriptor) {
344     if (vOps == NULL) {
345         ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
346         return BAD_VALUE;
347     }
348
349     int tagCount = vOps->get_tag_count(vOps);
350     if (tagCount < 0 || tagCount > INT32_MAX) {
351         ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
352         return BAD_VALUE;
353     }
354
355     Vector<uint32_t> tagArray;
356     LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
357             "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
358
359     vOps->get_all_tags(vOps, /*out*/tagArray.editArray());
360
361     sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
362     desc->mTagCount = tagCount;
363
364     SortedVector<String8> sections;
365     KeyedVector<uint32_t, String8> tagToSectionMap;
366
367     for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
368         uint32_t tag = tagArray[i];
369         if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
370             ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
371             return BAD_VALUE;
372         }
373         const char *tagName = vOps->get_tag_name(vOps, tag);
374         if (tagName == NULL) {
375             ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
376             return BAD_VALUE;
377         }
378         desc->mTagToNameMap.add(tag, String8(tagName));
379         const char *sectionName = vOps->get_section_name(vOps, tag);
380         if (sectionName == NULL) {
381             ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
382             return BAD_VALUE;
383         }
384
385         String8 sectionString(sectionName);
386
387         sections.add(sectionString);
388         tagToSectionMap.add(tag, sectionString);
389
390         int tagType = vOps->get_tag_type(vOps, tag);
391         if (tagType < 0 || tagType >= NUM_TYPES) {
392             ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
393             return BAD_VALUE;
394         }
395         desc->mTagToTypeMap.add(tag, tagType);
396     }
397
398     desc->mSections = sections;
399
400     for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
401         uint32_t tag = tagArray[i];
402         String8 sectionString = tagToSectionMap.valueFor(tag);
403
404         // Set up tag to section index map
405         ssize_t index = sections.indexOf(sectionString);
406         LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
407         desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
408
409         // Set up reverse mapping
410         ssize_t reverseIndex = -1;
411         if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
412             KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
413             reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
414         }
415         desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
416     }
417
418     descriptor = desc;
419     return OK;
420 }
421
422 status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
423     status_t res = OK;
424     Mutex::Autolock al(sLock);
425     sGlobalVendorTagDescriptor = desc;
426
427     vendor_tag_ops_t* opsPtr = NULL;
428     if (desc != NULL) {
429         opsPtr = &(desc->mVendorOps);
430         opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
431         opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
432         opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
433         opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
434         opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
435     }
436     if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
437         ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)."
438                 , __FUNCTION__, strerror(-res), res);
439     }
440     return res;
441 }
442
443 void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
444     Mutex::Autolock al(sLock);
445     set_camera_metadata_vendor_ops(NULL);
446     sGlobalVendorTagDescriptor.clear();
447 }
448
449 sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
450     Mutex::Autolock al(sLock);
451     return sGlobalVendorTagDescriptor;
452 }
453
454 extern "C" {
455
456 int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
457     Mutex::Autolock al(sLock);
458     if (sGlobalVendorTagDescriptor == NULL) {
459         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
460         return VENDOR_TAG_COUNT_ERR;
461     }
462     return sGlobalVendorTagDescriptor->getTagCount();
463 }
464
465 void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
466     Mutex::Autolock al(sLock);
467     if (sGlobalVendorTagDescriptor == NULL) {
468         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
469         return;
470     }
471     sGlobalVendorTagDescriptor->getTagArray(tagArray);
472 }
473
474 const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
475     Mutex::Autolock al(sLock);
476     if (sGlobalVendorTagDescriptor == NULL) {
477         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
478         return VENDOR_SECTION_NAME_ERR;
479     }
480     return sGlobalVendorTagDescriptor->getSectionName(tag);
481 }
482
483 const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
484     Mutex::Autolock al(sLock);
485     if (sGlobalVendorTagDescriptor == NULL) {
486         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
487         return VENDOR_TAG_NAME_ERR;
488     }
489     return sGlobalVendorTagDescriptor->getTagName(tag);
490 }
491
492 int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
493     Mutex::Autolock al(sLock);
494     if (sGlobalVendorTagDescriptor == NULL) {
495         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
496         return VENDOR_TAG_TYPE_ERR;
497     }
498     return sGlobalVendorTagDescriptor->getTagType(tag);
499 }
500
501 } /* extern "C" */
502 } /* namespace android */