1 /*
2  * Copyright (C) 2012 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_NDEBUG 0
18 
19 #define LOG_TAG "Camera2-Metadata"
20 #include <utils/Log.h>
21 #include <utils/Errors.h>
22 
23 #include <binder/Parcel.h>
24 #include <camera/CameraMetadata.h>
25 
26 namespace android {
27 
28 #define ALIGN_TO(val, alignment) \
29     (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
30 
31 typedef Parcel::WritableBlob WritableBlob;
32 typedef Parcel::ReadableBlob ReadableBlob;
33 
CameraMetadata()34 CameraMetadata::CameraMetadata() :
35         mBuffer(NULL), mLocked(false) {
36 }
37 
CameraMetadata(size_t entryCapacity,size_t dataCapacity)38 CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
39         mLocked(false)
40 {
41     mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
42 }
43 
CameraMetadata(const CameraMetadata & other)44 CameraMetadata::CameraMetadata(const CameraMetadata &other) :
45         mLocked(false) {
46     mBuffer = clone_camera_metadata(other.mBuffer);
47 }
48 
CameraMetadata(CameraMetadata && other)49 CameraMetadata::CameraMetadata(CameraMetadata &&other) :mBuffer(NULL),  mLocked(false) {
50     acquire(other);
51 }
52 
operator =(CameraMetadata && other)53 CameraMetadata &CameraMetadata::operator=(CameraMetadata &&other) {
54     acquire(other);
55     return *this;
56 }
57 
CameraMetadata(camera_metadata_t * buffer)58 CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
59         mBuffer(NULL), mLocked(false) {
60     acquire(buffer);
61 }
62 
operator =(const CameraMetadata & other)63 CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
64     return operator=(other.mBuffer);
65 }
66 
operator =(const camera_metadata_t * buffer)67 CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
68     if (mLocked) {
69         ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
70         return *this;
71     }
72 
73     if (CC_LIKELY(buffer != mBuffer)) {
74         camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
75         clear();
76         mBuffer = newBuffer;
77     }
78     return *this;
79 }
80 
~CameraMetadata()81 CameraMetadata::~CameraMetadata() {
82     mLocked = false;
83     clear();
84 }
85 
getAndLock() const86 const camera_metadata_t* CameraMetadata::getAndLock() const {
87     mLocked = true;
88     return mBuffer;
89 }
90 
unlock(const camera_metadata_t * buffer) const91 status_t CameraMetadata::unlock(const camera_metadata_t *buffer) const {
92     if (!mLocked) {
93         ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
94         return INVALID_OPERATION;
95     }
96     if (buffer != mBuffer) {
97         ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!",
98                 __FUNCTION__);
99         return BAD_VALUE;
100     }
101     mLocked = false;
102     return OK;
103 }
104 
release()105 camera_metadata_t* CameraMetadata::release() {
106     if (mLocked) {
107         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
108         return NULL;
109     }
110     camera_metadata_t *released = mBuffer;
111     mBuffer = NULL;
112     return released;
113 }
114 
clear()115 void CameraMetadata::clear() {
116     if (mLocked) {
117         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
118         return;
119     }
120     if (mBuffer) {
121         free_camera_metadata(mBuffer);
122         mBuffer = NULL;
123     }
124 }
125 
acquire(camera_metadata_t * buffer)126 void CameraMetadata::acquire(camera_metadata_t *buffer) {
127     if (mLocked) {
128         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
129         return;
130     }
131     clear();
132     mBuffer = buffer;
133 
134     ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK,
135              "%s: Failed to validate metadata structure %p",
136              __FUNCTION__, buffer);
137 }
138 
acquire(CameraMetadata & other)139 void CameraMetadata::acquire(CameraMetadata &other) {
140     if (mLocked) {
141         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
142         return;
143     }
144     acquire(other.release());
145 }
146 
append(const CameraMetadata & other)147 status_t CameraMetadata::append(const CameraMetadata &other) {
148     return append(other.mBuffer);
149 }
150 
append(const camera_metadata_t * other)151 status_t CameraMetadata::append(const camera_metadata_t* other) {
152     if (mLocked) {
153         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
154         return INVALID_OPERATION;
155     }
156     size_t extraEntries = get_camera_metadata_entry_count(other);
157     size_t extraData = get_camera_metadata_data_count(other);
158     resizeIfNeeded(extraEntries, extraData);
159 
160     return append_camera_metadata(mBuffer, other);
161 }
162 
entryCount() const163 size_t CameraMetadata::entryCount() const {
164     return (mBuffer == NULL) ? 0 :
165             get_camera_metadata_entry_count(mBuffer);
166 }
167 
isEmpty() const168 bool CameraMetadata::isEmpty() const {
169     return entryCount() == 0;
170 }
171 
sort()172 status_t CameraMetadata::sort() {
173     if (mLocked) {
174         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
175         return INVALID_OPERATION;
176     }
177     return sort_camera_metadata(mBuffer);
178 }
179 
checkType(uint32_t tag,uint8_t expectedType)180 status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
181     int tagType = get_local_camera_metadata_tag_type(tag, mBuffer);
182     if ( CC_UNLIKELY(tagType == -1)) {
183         ALOGE("Update metadata entry: Unknown tag %d", tag);
184         return INVALID_OPERATION;
185     }
186     if ( CC_UNLIKELY(tagType != expectedType) ) {
187         ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
188                 "got type %s data instead ",
189                 get_local_camera_metadata_tag_name(tag, mBuffer), tag,
190                 camera_metadata_type_names[tagType],
191                 camera_metadata_type_names[expectedType]);
192         return INVALID_OPERATION;
193     }
194     return OK;
195 }
196 
update(uint32_t tag,const int32_t * data,size_t data_count)197 status_t CameraMetadata::update(uint32_t tag,
198         const int32_t *data, size_t data_count) {
199     status_t res;
200     if (mLocked) {
201         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
202         return INVALID_OPERATION;
203     }
204     if ( (res = checkType(tag, TYPE_INT32)) != OK) {
205         return res;
206     }
207     return updateImpl(tag, (const void*)data, data_count);
208 }
209 
update(uint32_t tag,const uint8_t * data,size_t data_count)210 status_t CameraMetadata::update(uint32_t tag,
211         const uint8_t *data, size_t data_count) {
212     status_t res;
213     if (mLocked) {
214         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
215         return INVALID_OPERATION;
216     }
217     if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
218         return res;
219     }
220     return updateImpl(tag, (const void*)data, data_count);
221 }
222 
update(uint32_t tag,const float * data,size_t data_count)223 status_t CameraMetadata::update(uint32_t tag,
224         const float *data, size_t data_count) {
225     status_t res;
226     if (mLocked) {
227         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
228         return INVALID_OPERATION;
229     }
230     if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
231         return res;
232     }
233     return updateImpl(tag, (const void*)data, data_count);
234 }
235 
update(uint32_t tag,const int64_t * data,size_t data_count)236 status_t CameraMetadata::update(uint32_t tag,
237         const int64_t *data, size_t data_count) {
238     status_t res;
239     if (mLocked) {
240         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
241         return INVALID_OPERATION;
242     }
243     if ( (res = checkType(tag, TYPE_INT64)) != OK) {
244         return res;
245     }
246     return updateImpl(tag, (const void*)data, data_count);
247 }
248 
update(uint32_t tag,const double * data,size_t data_count)249 status_t CameraMetadata::update(uint32_t tag,
250         const double *data, size_t data_count) {
251     status_t res;
252     if (mLocked) {
253         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
254         return INVALID_OPERATION;
255     }
256     if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
257         return res;
258     }
259     return updateImpl(tag, (const void*)data, data_count);
260 }
261 
update(uint32_t tag,const camera_metadata_rational_t * data,size_t data_count)262 status_t CameraMetadata::update(uint32_t tag,
263         const camera_metadata_rational_t *data, size_t data_count) {
264     status_t res;
265     if (mLocked) {
266         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
267         return INVALID_OPERATION;
268     }
269     if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
270         return res;
271     }
272     return updateImpl(tag, (const void*)data, data_count);
273 }
274 
update(uint32_t tag,const String8 & string)275 status_t CameraMetadata::update(uint32_t tag,
276         const String8 &string) {
277     status_t res;
278     if (mLocked) {
279         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
280         return INVALID_OPERATION;
281     }
282     if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
283         return res;
284     }
285     // string.size() doesn't count the null termination character.
286     return updateImpl(tag, (const void*)string.string(), string.size() + 1);
287 }
288 
update(const camera_metadata_ro_entry & entry)289 status_t CameraMetadata::update(const camera_metadata_ro_entry &entry) {
290     status_t res;
291     if (mLocked) {
292         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
293         return INVALID_OPERATION;
294     }
295     if ( (res = checkType(entry.tag, entry.type)) != OK) {
296         return res;
297     }
298     return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
299 }
300 
updateImpl(uint32_t tag,const void * data,size_t data_count)301 status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
302         size_t data_count) {
303     status_t res;
304     if (mLocked) {
305         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
306         return INVALID_OPERATION;
307     }
308     int type = get_local_camera_metadata_tag_type(tag, mBuffer);
309     if (type == -1) {
310         ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
311         return BAD_VALUE;
312     }
313     // Safety check - ensure that data isn't pointing to this metadata, since
314     // that would get invalidated if a resize is needed
315     size_t bufferSize = get_camera_metadata_size(mBuffer);
316     uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
317     uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
318     if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
319         ALOGE("%s: Update attempted with data from the same metadata buffer!",
320                 __FUNCTION__);
321         return INVALID_OPERATION;
322     }
323 
324     size_t data_size = calculate_camera_metadata_entry_data_size(type,
325             data_count);
326 
327     res = resizeIfNeeded(1, data_size);
328 
329     if (res == OK) {
330         camera_metadata_entry_t entry;
331         res = find_camera_metadata_entry(mBuffer, tag, &entry);
332         if (res == NAME_NOT_FOUND) {
333             res = add_camera_metadata_entry(mBuffer,
334                     tag, data, data_count);
335         } else if (res == OK) {
336             res = update_camera_metadata_entry(mBuffer,
337                     entry.index, data, data_count, NULL);
338         }
339     }
340 
341     if (res != OK) {
342         ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
343                 __FUNCTION__, get_local_camera_metadata_section_name(tag, mBuffer),
344                 get_local_camera_metadata_tag_name(tag, mBuffer), tag,
345                 strerror(-res), res);
346     }
347 
348     IF_ALOGV() {
349         ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
350                  OK,
351 
352                  "%s: Failed to validate metadata structure after update %p",
353                  __FUNCTION__, mBuffer);
354     }
355 
356     return res;
357 }
358 
exists(uint32_t tag) const359 bool CameraMetadata::exists(uint32_t tag) const {
360     camera_metadata_ro_entry entry;
361     return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
362 }
363 
find(uint32_t tag)364 camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
365     status_t res;
366     camera_metadata_entry entry;
367     if (mLocked) {
368         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
369         entry.count = 0;
370         return entry;
371     }
372     res = find_camera_metadata_entry(mBuffer, tag, &entry);
373     if (CC_UNLIKELY( res != OK )) {
374         entry.count = 0;
375         entry.data.u8 = NULL;
376     }
377     return entry;
378 }
379 
find(uint32_t tag) const380 camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
381     status_t res;
382     camera_metadata_ro_entry entry;
383     res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
384     if (CC_UNLIKELY( res != OK )) {
385         entry.count = 0;
386         entry.data.u8 = NULL;
387     }
388     return entry;
389 }
390 
erase(uint32_t tag)391 status_t CameraMetadata::erase(uint32_t tag) {
392     camera_metadata_entry_t entry;
393     status_t res;
394     if (mLocked) {
395         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
396         return INVALID_OPERATION;
397     }
398     res = find_camera_metadata_entry(mBuffer, tag, &entry);
399     if (res == NAME_NOT_FOUND) {
400         return OK;
401     } else if (res != OK) {
402         ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
403                 __FUNCTION__,
404                 get_local_camera_metadata_section_name(tag, mBuffer),
405                 get_local_camera_metadata_tag_name(tag, mBuffer),
406                 tag, strerror(-res), res);
407         return res;
408     }
409     res = delete_camera_metadata_entry(mBuffer, entry.index);
410     if (res != OK) {
411         ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
412                 __FUNCTION__,
413                 get_local_camera_metadata_section_name(tag, mBuffer),
414                 get_local_camera_metadata_tag_name(tag, mBuffer),
415                 tag, strerror(-res), res);
416     }
417     return res;
418 }
419 
removePermissionEntries(metadata_vendor_id_t vendorId,std::vector<int32_t> * tagsRemoved)420 status_t CameraMetadata::removePermissionEntries(metadata_vendor_id_t vendorId,
421         std::vector<int32_t> *tagsRemoved) {
422     uint32_t tagCount = 0;
423     std::vector<uint32_t> tagsToRemove;
424 
425     if (tagsRemoved == nullptr) {
426         return BAD_VALUE;
427     }
428 
429     sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor();
430     if ((nullptr == vTags.get()) || (0 >= vTags->getTagCount())) {
431         sp<VendorTagDescriptorCache> cache =
432             VendorTagDescriptorCache::getGlobalVendorTagCache();
433         if (cache.get()) {
434             cache->getVendorTagDescriptor(vendorId, &vTags);
435         }
436     }
437 
438     if ((nullptr != vTags.get()) && (vTags->getTagCount() > 0)) {
439         tagCount = vTags->getTagCount();
440         uint32_t *vendorTags = new uint32_t[tagCount];
441         if (nullptr == vendorTags) {
442             return NO_MEMORY;
443         }
444         vTags->getTagArray(vendorTags);
445 
446         tagsToRemove.reserve(tagCount);
447         tagsToRemove.insert(tagsToRemove.begin(), vendorTags, vendorTags + tagCount);
448 
449         delete [] vendorTags;
450         tagCount = 0;
451     }
452 
453     auto tagsNeedingPermission = get_camera_metadata_permission_needed(&tagCount);
454     if (tagCount > 0) {
455         tagsToRemove.reserve(tagsToRemove.capacity() + tagCount);
456         tagsToRemove.insert(tagsToRemove.end(), tagsNeedingPermission,
457                 tagsNeedingPermission + tagCount);
458     }
459 
460     tagsRemoved->reserve(tagsToRemove.size());
461     for (const auto &it : tagsToRemove) {
462         if (exists(it)) {
463             auto rc = erase(it);
464             if (NO_ERROR != rc) {
465                 ALOGE("%s: Failed to erase tag: %x", __func__, it);
466                 return rc;
467             }
468             tagsRemoved->push_back(it);
469         }
470     }
471 
472     // Update the available characterstics accordingly
473     if (exists(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS)) {
474         std::vector<uint32_t> currentKeys;
475 
476         std::sort(tagsRemoved->begin(), tagsRemoved->end());
477         auto keys = find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
478         currentKeys.reserve(keys.count);
479         currentKeys.insert(currentKeys.end(), keys.data.i32, keys.data.i32 + keys.count);
480         std::sort(currentKeys.begin(), currentKeys.end());
481 
482         std::vector<int32_t> newKeys(keys.count);
483         auto end = std::set_difference(currentKeys.begin(), currentKeys.end(), tagsRemoved->begin(),
484                 tagsRemoved->end(), newKeys.begin());
485         newKeys.resize(end - newKeys.begin());
486 
487         update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, newKeys.data(), newKeys.size());
488     }
489 
490     return NO_ERROR;
491 }
492 
dump(int fd,int verbosity,int indentation) const493 void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
494     dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
495 }
496 
resizeIfNeeded(size_t extraEntries,size_t extraData)497 status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
498     if (mBuffer == NULL) {
499         mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
500         if (mBuffer == NULL) {
501             ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
502             return NO_MEMORY;
503         }
504     } else {
505         size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
506         size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
507         size_t newEntryCount = currentEntryCount +
508                 extraEntries;
509         newEntryCount = (newEntryCount > currentEntryCap) ?
510                 newEntryCount * 2 : currentEntryCap;
511 
512         size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
513         size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
514         size_t newDataCount = currentDataCount +
515                 extraData;
516         newDataCount = (newDataCount > currentDataCap) ?
517                 newDataCount * 2 : currentDataCap;
518 
519         if (newEntryCount > currentEntryCap ||
520                 newDataCount > currentDataCap) {
521             camera_metadata_t *oldBuffer = mBuffer;
522             mBuffer = allocate_camera_metadata(newEntryCount,
523                     newDataCount);
524             if (mBuffer == NULL) {
525                 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
526                 return NO_MEMORY;
527             }
528             append_camera_metadata(mBuffer, oldBuffer);
529             free_camera_metadata(oldBuffer);
530         }
531     }
532     return OK;
533 }
534 
readFromParcel(const Parcel & data,camera_metadata_t ** out)535 status_t CameraMetadata::readFromParcel(const Parcel& data,
536                                         camera_metadata_t** out) {
537 
538     status_t err = OK;
539 
540     camera_metadata_t* metadata = NULL;
541 
542     if (out) {
543         *out = NULL;
544     }
545 
546     // See CameraMetadata::writeToParcel for parcel data layout diagram and explanation.
547     // arg0 = blobSize (int32)
548     int32_t blobSizeTmp = -1;
549     if ((err = data.readInt32(&blobSizeTmp)) != OK) {
550         ALOGE("%s: Failed to read metadata size (error %d %s)",
551               __FUNCTION__, err, strerror(-err));
552         return err;
553     }
554     const size_t blobSize = static_cast<size_t>(blobSizeTmp);
555     const size_t alignment = get_camera_metadata_alignment();
556 
557     // Special case: zero blob size means zero sized (NULL) metadata.
558     if (blobSize == 0) {
559         ALOGV("%s: Read 0-sized metadata", __FUNCTION__);
560         return OK;
561     }
562 
563     if (blobSize <= alignment) {
564         ALOGE("%s: metadata blob is malformed, blobSize(%zu) should be larger than alignment(%zu)",
565                 __FUNCTION__, blobSize, alignment);
566         return BAD_VALUE;
567     }
568 
569     const size_t metadataSize = blobSize - alignment;
570 
571     // NOTE: this doesn't make sense to me. shouldn't the blob
572     // know how big it is? why do we have to specify the size
573     // to Parcel::readBlob ?
574     ReadableBlob blob;
575     // arg1 = metadata (blob)
576     do {
577         if ((err = data.readBlob(blobSize, &blob)) != OK) {
578             ALOGE("%s: Failed to read metadata blob (sized %zu). Possible "
579                   " serialization bug. Error %d %s",
580                   __FUNCTION__, blobSize, err, strerror(-err));
581             break;
582         }
583 
584         // arg2 = offset (blob)
585         // Must be after blob since we don't know offset until after writeBlob.
586         int32_t offsetTmp;
587         if ((err = data.readInt32(&offsetTmp)) != OK) {
588             ALOGE("%s: Failed to read metadata offsetTmp (error %d %s)",
589                   __FUNCTION__, err, strerror(-err));
590             break;
591         }
592         const size_t offset = static_cast<size_t>(offsetTmp);
593         if (offset >= alignment) {
594             ALOGE("%s: metadata offset(%zu) should be less than alignment(%zu)",
595                     __FUNCTION__, blobSize, alignment);
596             err = BAD_VALUE;
597             break;
598         }
599 
600         const uintptr_t metadataStart = reinterpret_cast<uintptr_t>(blob.data()) + offset;
601         const camera_metadata_t* tmp =
602                        reinterpret_cast<const camera_metadata_t*>(metadataStart);
603         ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
604                 __FUNCTION__, alignment, tmp, offset);
605         metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize);
606         if (metadata == NULL) {
607             // We consider that allocation only fails if the validation
608             // also failed, therefore the readFromParcel was a failure.
609             ALOGE("%s: metadata allocation and copy failed", __FUNCTION__);
610             err = BAD_VALUE;
611         }
612     } while(0);
613     blob.release();
614 
615     if (out) {
616         ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata);
617         *out = metadata;
618     } else if (metadata != NULL) {
619         ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata);
620         free_camera_metadata(metadata);
621     }
622 
623     return err;
624 }
625 
writeToParcel(Parcel & data,const camera_metadata_t * metadata)626 status_t CameraMetadata::writeToParcel(Parcel& data,
627                                        const camera_metadata_t* metadata) {
628     status_t res = OK;
629 
630     /**
631      * Below is the camera metadata parcel layout:
632      *
633      * |--------------------------------------------|
634      * |             arg0: blobSize                 |
635      * |              (length = 4)                  |
636      * |--------------------------------------------|<--Skip the rest if blobSize == 0.
637      * |                                            |
638      * |                                            |
639      * |              arg1: blob                    |
640      * | (length = variable, see arg1 layout below) |
641      * |                                            |
642      * |                                            |
643      * |--------------------------------------------|
644      * |              arg2: offset                  |
645      * |              (length = 4)                  |
646      * |--------------------------------------------|
647      */
648 
649     // arg0 = blobSize (int32)
650     if (metadata == NULL) {
651         // Write zero blobSize for null metadata.
652         return data.writeInt32(0);
653     }
654 
655     /**
656      * Always make the blob size sufficiently larger, as we need put alignment
657      * padding and metadata into the blob. Since we don't know the alignment
658      * offset before writeBlob. Then write the metadata to aligned offset.
659      */
660     const size_t metadataSize = get_camera_metadata_compact_size(metadata);
661     const size_t alignment = get_camera_metadata_alignment();
662     const size_t blobSize = metadataSize + alignment;
663     res = data.writeInt32(static_cast<int32_t>(blobSize));
664     if (res != OK) {
665         return res;
666     }
667 
668     size_t offset = 0;
669     /**
670      * arg1 = metadata (blob).
671      *
672      * The blob size is the sum of front padding size, metadata size and back padding
673      * size, which is equal to metadataSize + alignment.
674      *
675      * The blob layout is:
676      * |------------------------------------|<----Start address of the blob (unaligned).
677      * |           front padding            |
678      * |          (size = offset)           |
679      * |------------------------------------|<----Aligned start address of metadata.
680      * |                                    |
681      * |                                    |
682      * |            metadata                |
683      * |       (size = metadataSize)        |
684      * |                                    |
685      * |                                    |
686      * |------------------------------------|
687      * |           back padding             |
688      * |     (size = alignment - offset)    |
689      * |------------------------------------|<----End address of blob.
690      *                                            (Blob start address + blob size).
691      */
692     WritableBlob blob;
693     do {
694         res = data.writeBlob(blobSize, false, &blob);
695         if (res != OK) {
696             break;
697         }
698         const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment);
699         offset = metadataStart - reinterpret_cast<uintptr_t>(blob.data());
700         ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
701                 __FUNCTION__, alignment,
702                 reinterpret_cast<const void *>(metadataStart), offset);
703         copy_camera_metadata(reinterpret_cast<void*>(metadataStart), metadataSize, metadata);
704 
705         // Not too big of a problem since receiving side does hard validation
706         // Don't check the size since the compact size could be larger
707         if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) {
708             ALOGW("%s: Failed to validate metadata %p before writing blob",
709                    __FUNCTION__, metadata);
710         }
711 
712     } while(false);
713     blob.release();
714 
715     // arg2 = offset (int32)
716     res = data.writeInt32(static_cast<int32_t>(offset));
717 
718     return res;
719 }
720 
readFromParcel(const Parcel * parcel)721 status_t CameraMetadata::readFromParcel(const Parcel *parcel) {
722 
723     ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
724 
725     status_t res = OK;
726 
727     if (parcel == NULL) {
728         ALOGE("%s: parcel is null", __FUNCTION__);
729         return BAD_VALUE;
730     }
731 
732     if (mLocked) {
733         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
734         return INVALID_OPERATION;
735     }
736 
737     camera_metadata *buffer = NULL;
738     // TODO: reading should return a status code, in case validation fails
739     res = CameraMetadata::readFromParcel(*parcel, &buffer);
740 
741     if (res != NO_ERROR) {
742         ALOGE("%s: Failed to read from parcel. Metadata is unchanged.",
743               __FUNCTION__);
744         return res;
745     }
746 
747     clear();
748     mBuffer = buffer;
749 
750     return OK;
751 }
752 
writeToParcel(Parcel * parcel) const753 status_t CameraMetadata::writeToParcel(Parcel *parcel) const {
754 
755     ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
756 
757     if (parcel == NULL) {
758         ALOGE("%s: parcel is null", __FUNCTION__);
759         return BAD_VALUE;
760     }
761 
762     return CameraMetadata::writeToParcel(*parcel, mBuffer);
763 }
764 
swap(CameraMetadata & other)765 void CameraMetadata::swap(CameraMetadata& other) {
766     if (mLocked) {
767         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
768         return;
769     } else if (other.mLocked) {
770         ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
771         return;
772     }
773 
774     camera_metadata* thisBuf = mBuffer;
775     camera_metadata* otherBuf = other.mBuffer;
776 
777     other.mBuffer = thisBuf;
778     mBuffer = otherBuf;
779 }
780 
getTagFromName(const char * name,const VendorTagDescriptor * vTags,uint32_t * tag)781 status_t CameraMetadata::getTagFromName(const char *name,
782         const VendorTagDescriptor* vTags, uint32_t *tag) {
783 
784     if (name == nullptr || tag == nullptr) return BAD_VALUE;
785 
786     size_t nameLength = strlen(name);
787 
788     const SortedVector<String8> *vendorSections;
789     size_t vendorSectionCount = 0;
790 
791     if (vTags != NULL) {
792         vendorSections = vTags->getAllSectionNames();
793         vendorSectionCount = vendorSections->size();
794     }
795 
796     // First, find the section by the longest string match
797     const char *section = NULL;
798     size_t sectionIndex = 0;
799     size_t sectionLength = 0;
800     size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
801     for (size_t i = 0; i < totalSectionCount; ++i) {
802 
803         const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
804                 (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
805 
806         ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
807 
808         if (strstr(name, str) == name) { // name begins with the section name
809             size_t strLength = strlen(str);
810 
811             ALOGV("%s: Name begins with section name", __FUNCTION__);
812 
813             // section name is the longest we've found so far
814             if (section == NULL || sectionLength < strLength) {
815                 section = str;
816                 sectionIndex = i;
817                 sectionLength = strLength;
818 
819                 ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
820             }
821         }
822     }
823 
824     // TODO: Make above get_camera_metadata_section_from_name ?
825 
826     if (section == NULL) {
827         return NAME_NOT_FOUND;
828     } else {
829         ALOGV("%s: Found matched section '%s' (%zu)",
830               __FUNCTION__, section, sectionIndex);
831     }
832 
833     // Get the tag name component of the name
834     const char *nameTagName = name + sectionLength + 1; // x.y.z -> z
835     if (sectionLength + 1 >= nameLength) {
836         return BAD_VALUE;
837     }
838 
839     // Match rest of name against the tag names in that section only
840     uint32_t candidateTag = 0;
841     if (sectionIndex < ANDROID_SECTION_COUNT) {
842         // Match built-in tags (typically android.*)
843         uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
844         tagBegin = camera_metadata_section_bounds[sectionIndex][0];
845         tagEnd = camera_metadata_section_bounds[sectionIndex][1];
846 
847         for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
848             const char *tagName = get_camera_metadata_tag_name(candidateTag);
849 
850             if (strcmp(nameTagName, tagName) == 0) {
851                 ALOGV("%s: Found matched tag '%s' (%d)",
852                       __FUNCTION__, tagName, candidateTag);
853                 break;
854             }
855         }
856 
857         if (candidateTag == tagEnd) {
858             return NAME_NOT_FOUND;
859         }
860     } else if (vTags != NULL) {
861         // Match vendor tags (typically com.*)
862         const String8 sectionName(section);
863         const String8 tagName(nameTagName);
864 
865         status_t res = OK;
866         if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
867             return NAME_NOT_FOUND;
868         }
869     }
870 
871     *tag = candidateTag;
872     return OK;
873 }
874 
875 
876 }; // namespace android
877