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