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