1 /*
2 * Copyright (C) 2019 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 #define LOG_TAG "GCH_HalCameraMetadata"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22
23 #include <inttypes.h>
24
25 #include "hal_camera_metadata.h"
26
27 namespace android {
28 namespace google_camera_hal {
29
Create(camera_metadata_t * metadata)30 std::unique_ptr<HalCameraMetadata> HalCameraMetadata::Create(
31 camera_metadata_t* metadata) {
32 if (metadata == nullptr) {
33 ALOGE("%s: metadata cannot be nullptr.", __FUNCTION__);
34 return nullptr;
35 }
36
37 auto hal_metadata =
38 std::unique_ptr<HalCameraMetadata>(new HalCameraMetadata(metadata));
39 if (hal_metadata == nullptr) {
40 ALOGE("%s: Creating HalCameraMetadata failed.", __FUNCTION__);
41 return nullptr;
42 }
43
44 return hal_metadata;
45 }
46
Create(size_t entry_capacity,size_t data_capacity)47 std::unique_ptr<HalCameraMetadata> HalCameraMetadata::Create(
48 size_t entry_capacity, size_t data_capacity) {
49 camera_metadata_t* metadata =
50 allocate_camera_metadata(entry_capacity, data_capacity);
51 if (metadata == nullptr) {
52 ALOGE("%s: Allocating camera metadata failed.", __FUNCTION__);
53 return nullptr;
54 }
55
56 auto hal_metadata = Create(metadata);
57 if (hal_metadata == nullptr) {
58 free_camera_metadata(metadata);
59 return nullptr;
60 }
61
62 return hal_metadata;
63 }
64
Clone(const camera_metadata_t * metadata)65 std::unique_ptr<HalCameraMetadata> HalCameraMetadata::Clone(
66 const camera_metadata_t* metadata) {
67 if (metadata == nullptr) {
68 ALOGE("%s: metadata cannot be nullptr.", __FUNCTION__);
69 return nullptr;
70 }
71
72 camera_metadata_t* cloned_metadata = clone_camera_metadata(metadata);
73 if (cloned_metadata == nullptr) {
74 ALOGE("%s: Cloning camera metadata failed.", __FUNCTION__);
75 return nullptr;
76 }
77
78 auto hal_metadata = Create(cloned_metadata);
79 if (hal_metadata == nullptr) {
80 free_camera_metadata(cloned_metadata);
81 return nullptr;
82 }
83
84 return hal_metadata;
85 }
86
Clone(const HalCameraMetadata * hal_metadata)87 std::unique_ptr<HalCameraMetadata> HalCameraMetadata::Clone(
88 const HalCameraMetadata* hal_metadata) {
89 if (hal_metadata == nullptr) {
90 return nullptr;
91 }
92
93 return Clone(hal_metadata->metadata_);
94 }
95
~HalCameraMetadata()96 HalCameraMetadata::~HalCameraMetadata() {
97 std::unique_lock<std::mutex> lock(metadata_lock_);
98
99 if (metadata_ != nullptr) {
100 free_camera_metadata(metadata_);
101 }
102 }
103
HalCameraMetadata(camera_metadata_t * metadata)104 HalCameraMetadata::HalCameraMetadata(camera_metadata_t* metadata)
105 : metadata_(metadata) {
106 }
107
ReleaseCameraMetadata()108 camera_metadata_t* HalCameraMetadata::ReleaseCameraMetadata() {
109 std::unique_lock<std::mutex> lock(metadata_lock_);
110
111 camera_metadata_t* metadata = metadata_;
112 metadata_ = nullptr;
113
114 return metadata;
115 }
116
GetRawCameraMetadata() const117 const camera_metadata_t* HalCameraMetadata::GetRawCameraMetadata() const {
118 return metadata_;
119 }
120
GetCameraMetadataSize() const121 size_t HalCameraMetadata::GetCameraMetadataSize() const {
122 std::unique_lock<std::mutex> lock(metadata_lock_);
123
124 if (metadata_ == nullptr) {
125 return 0;
126 }
127
128 return get_camera_metadata_size(metadata_);
129 }
130
ResizeIfNeeded(size_t extra_entries,size_t extra_data)131 status_t HalCameraMetadata::ResizeIfNeeded(size_t extra_entries,
132 size_t extra_data) {
133 bool resize = false;
134 size_t current_entry_cap = get_camera_metadata_entry_capacity(metadata_);
135 size_t new_entry_count =
136 get_camera_metadata_entry_count(metadata_) + extra_entries;
137 if (new_entry_count > current_entry_cap) {
138 new_entry_count = new_entry_count * 2;
139 resize = true;
140 } else {
141 new_entry_count = current_entry_cap;
142 }
143
144 size_t current_data_count = get_camera_metadata_data_count(metadata_);
145 size_t current_data_cap = get_camera_metadata_data_capacity(metadata_);
146 size_t new_data_count = current_data_count + extra_data;
147 if (new_data_count > current_data_cap) {
148 new_data_count = new_data_count * 2;
149 resize = true;
150 } else {
151 new_data_count = current_data_cap;
152 }
153
154 if (resize) {
155 camera_metadata_t* metadata = metadata_;
156 metadata_ = allocate_camera_metadata(new_entry_count, new_data_count);
157 if (metadata_ == nullptr) {
158 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
159 metadata_ = metadata;
160 return NO_MEMORY;
161 }
162 append_camera_metadata(metadata_, metadata);
163 free_camera_metadata(metadata);
164 }
165
166 return OK;
167 }
168
SetMetadataRaw(uint32_t tag,const void * data,size_t data_count)169 status_t HalCameraMetadata::SetMetadataRaw(uint32_t tag, const void* data,
170 size_t data_count) {
171 status_t res;
172 int type = get_camera_metadata_tag_type(tag);
173 if (type == -1) {
174 ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
175 return BAD_VALUE;
176 }
177 // Safety check - ensure that data isn't pointing to this metadata, since
178 // that would get invalidated if a resize is needed
179 size_t buffer_size = get_camera_metadata_size(metadata_);
180 uintptr_t buffer_addr = reinterpret_cast<uintptr_t>(metadata_);
181 uintptr_t data_addr = reinterpret_cast<uintptr_t>(data);
182 if (data_addr > buffer_addr && data_addr < (buffer_addr + buffer_size)) {
183 ALOGE("%s: Update attempted with data from the same metadata buffer!",
184 __FUNCTION__);
185 return INVALID_OPERATION;
186 }
187
188 size_t size = calculate_camera_metadata_entry_data_size(type, data_count);
189 res = ResizeIfNeeded(/*extra_entries=*/1, size);
190 if (res != OK) {
191 ALOGE("%s: Resize fail", __FUNCTION__);
192 return res;
193 }
194
195 camera_metadata_entry_t entry;
196 res = find_camera_metadata_entry(metadata_, tag, &entry);
197 if (res == NAME_NOT_FOUND) {
198 res = add_camera_metadata_entry(metadata_, tag, data, data_count);
199 } else if (res == OK) {
200 res = update_camera_metadata_entry(metadata_, entry.index, data, data_count,
201 nullptr);
202 }
203
204 return res;
205 }
206
IsTypeValid(uint32_t tag,int32_t expected_type)207 bool HalCameraMetadata::IsTypeValid(uint32_t tag, int32_t expected_type) {
208 int32_t type = get_camera_metadata_tag_type(tag);
209 if (type == -1) {
210 ALOGE("%s: Unknown tag 0x%x.", __FUNCTION__, tag);
211 return false;
212 }
213 if (type != expected_type) {
214 ALOGE("%s: mismatched type (%d) from tag 0x%x. Expected type is %d",
215 __FUNCTION__, type, tag, expected_type);
216 return false;
217 }
218 return true;
219 }
220
Set(uint32_t tag,const uint8_t * data,uint32_t data_count)221 status_t HalCameraMetadata::Set(uint32_t tag, const uint8_t* data,
222 uint32_t data_count) {
223 std::unique_lock<std::mutex> lock(metadata_lock_);
224
225 if (metadata_ == nullptr) {
226 ALOGE("%s: metadata_ is nullptr", __FUNCTION__);
227 return INVALID_OPERATION;
228 }
229 if (IsTypeValid(tag, TYPE_BYTE) == false) {
230 return INVALID_OPERATION;
231 }
232 return SetMetadataRaw(tag, reinterpret_cast<const void*>(data), data_count);
233 }
234
Set(uint32_t tag,const int32_t * data,uint32_t data_count)235 status_t HalCameraMetadata::Set(uint32_t tag, const int32_t* data,
236 uint32_t data_count) {
237 std::unique_lock<std::mutex> lock(metadata_lock_);
238
239 if (metadata_ == nullptr) {
240 ALOGE("%s: metadata_ is nullptr", __FUNCTION__);
241 return INVALID_OPERATION;
242 }
243 if (IsTypeValid(tag, TYPE_INT32) == false) {
244 return INVALID_OPERATION;
245 }
246 return SetMetadataRaw(tag, reinterpret_cast<const void*>(data), data_count);
247 }
248
Set(uint32_t tag,const float * data,uint32_t data_count)249 status_t HalCameraMetadata::Set(uint32_t tag, const float* data,
250 uint32_t data_count) {
251 std::unique_lock<std::mutex> lock(metadata_lock_);
252
253 if (metadata_ == nullptr) {
254 ALOGE("%s: metadata_ is nullptr", __FUNCTION__);
255 return INVALID_OPERATION;
256 }
257 if (IsTypeValid(tag, TYPE_FLOAT) == false) {
258 return INVALID_OPERATION;
259 }
260 return SetMetadataRaw(tag, reinterpret_cast<const void*>(data), data_count);
261 }
262
Set(uint32_t tag,const int64_t * data,uint32_t data_count)263 status_t HalCameraMetadata::Set(uint32_t tag, const int64_t* data,
264 uint32_t data_count) {
265 std::unique_lock<std::mutex> lock(metadata_lock_);
266
267 if (metadata_ == nullptr) {
268 ALOGE("%s: metadata_ is nullptr", __FUNCTION__);
269 return INVALID_OPERATION;
270 }
271 if (IsTypeValid(tag, TYPE_INT64) == false) {
272 return INVALID_OPERATION;
273 }
274 return SetMetadataRaw(tag, reinterpret_cast<const void*>(data), data_count);
275 }
276
Set(uint32_t tag,const double * data,uint32_t data_count)277 status_t HalCameraMetadata::Set(uint32_t tag, const double* data,
278 uint32_t data_count) {
279 std::unique_lock<std::mutex> lock(metadata_lock_);
280
281 if (metadata_ == nullptr) {
282 ALOGE("%s: metadata_ is nullptr", __FUNCTION__);
283 return INVALID_OPERATION;
284 }
285 if (IsTypeValid(tag, TYPE_DOUBLE) == false) {
286 return INVALID_OPERATION;
287 }
288 return SetMetadataRaw(tag, reinterpret_cast<const void*>(data), data_count);
289 }
290
Set(uint32_t tag,const camera_metadata_rational_t * data,uint32_t data_count)291 status_t HalCameraMetadata::Set(uint32_t tag,
292 const camera_metadata_rational_t* data,
293 uint32_t data_count) {
294 std::unique_lock<std::mutex> lock(metadata_lock_);
295
296 if (metadata_ == nullptr) {
297 ALOGE("%s: metadata_ is nullptr", __FUNCTION__);
298 return INVALID_OPERATION;
299 }
300 if (IsTypeValid(tag, TYPE_RATIONAL) == false) {
301 return INVALID_OPERATION;
302 }
303 return SetMetadataRaw(tag, reinterpret_cast<const void*>(data), data_count);
304 }
305
Set(uint32_t tag,const std::string & string)306 status_t HalCameraMetadata::Set(uint32_t tag, const std::string& string) {
307 std::unique_lock<std::mutex> lock(metadata_lock_);
308
309 if (metadata_ == nullptr) {
310 ALOGE("%s: metadata_ is nullptr", __FUNCTION__);
311 return INVALID_OPERATION;
312 }
313 if (IsTypeValid(tag, TYPE_BYTE) == false) {
314 return INVALID_OPERATION;
315 }
316 // string length +1 for null-terminated character.
317 return SetMetadataRaw(tag, reinterpret_cast<const void*>(string.c_str()),
318 string.length() + 1);
319 }
320
Set(const camera_metadata_ro_entry & entry)321 status_t HalCameraMetadata::Set(const camera_metadata_ro_entry& entry) {
322 status_t res;
323
324 int32_t type = get_camera_metadata_tag_type(entry.tag);
325
326 switch (type) {
327 case TYPE_BYTE:
328 res = Set(entry.tag, entry.data.u8, entry.count);
329 break;
330 case TYPE_INT32:
331 res = Set(entry.tag, entry.data.i32, entry.count);
332 break;
333 case TYPE_FLOAT:
334 res = Set(entry.tag, entry.data.f, entry.count);
335 break;
336 case TYPE_INT64:
337 res = Set(entry.tag, entry.data.i64, entry.count);
338 break;
339 case TYPE_DOUBLE:
340 res = Set(entry.tag, entry.data.d, entry.count);
341 break;
342 case TYPE_RATIONAL:
343 res = Set(entry.tag, entry.data.r, entry.count);
344 break;
345 default:
346 ALOGE("%s: Unknown type in tag 0x%x.", __FUNCTION__, entry.tag);
347 res = BAD_TYPE;
348 break;
349 }
350
351 return res;
352 }
353
Get(uint32_t tag,camera_metadata_ro_entry * entry) const354 status_t HalCameraMetadata::Get(uint32_t tag,
355 camera_metadata_ro_entry* entry) const {
356 if (entry == nullptr) {
357 ALOGE("%s: entry is nullptr", __FUNCTION__);
358 return BAD_VALUE;
359 }
360
361 std::unique_lock<std::mutex> lock(metadata_lock_);
362 return find_camera_metadata_ro_entry(metadata_, tag, entry);
363 }
364
GetByIndex(camera_metadata_ro_entry * entry,size_t entry_index) const365 status_t HalCameraMetadata::GetByIndex(camera_metadata_ro_entry* entry,
366 size_t entry_index) const {
367 if (entry == nullptr) {
368 ALOGE("%s: entry is nullptr", __FUNCTION__);
369 return BAD_VALUE;
370 }
371
372 std::unique_lock<std::mutex> lock(metadata_lock_);
373 size_t entry_count = get_camera_metadata_entry_count(metadata_);
374 if (entry_index >= entry_count) {
375 ALOGE("%s: entry_index (%zu) >= entry_count(%zu)", __FUNCTION__,
376 entry_index, entry_count);
377 return BAD_VALUE;
378 }
379
380 return get_camera_metadata_ro_entry(metadata_, entry_index, entry);
381 }
382
Erase(const std::unordered_set<uint32_t> & tags)383 status_t HalCameraMetadata::Erase(const std::unordered_set<uint32_t>& tags) {
384 std::unique_lock<std::mutex> lock(metadata_lock_);
385 camera_metadata_ro_entry_t entry;
386 status_t res;
387
388 // Metadata entries to copy over; entries whose tag IDs aren't in 'tags'
389 std::vector<size_t> entry_indices;
390 size_t data_count = get_camera_metadata_data_count(metadata_);
391 size_t entry_count = get_camera_metadata_entry_count(metadata_);
392 size_t data_count_removed = 0;
393 for (size_t entry_index = 0; entry_index < entry_count; entry_index++) {
394 res = get_camera_metadata_ro_entry(metadata_, entry_index, &entry);
395 if (res != OK) {
396 ALOGE("%s: Error getting entry at index %zu: %s %d", __FUNCTION__,
397 entry_index, strerror(-res), res);
398 continue;
399 }
400
401 // See if the entry at the current index has a tag ID in the list of IDs
402 // that we'd like to remove
403 if (tags.find(entry.tag) != tags.end()) {
404 data_count_removed +=
405 calculate_camera_metadata_entry_data_size(entry.type, entry.count);
406 } else {
407 entry_indices.push_back(entry_index);
408 }
409 }
410
411 if (data_count_removed > data_count) {
412 // Sanity; this should never happen unless there is an implementation error
413 ALOGE("%s: Error! Cannot remove %zu bytes of data when there is only %zu",
414 __FUNCTION__, data_count_removed, data_count);
415 return UNKNOWN_ERROR;
416 } else if (data_count_removed == 0) {
417 // Nothing to remove
418 return OK;
419 }
420
421 size_t new_data_count = (data_count - data_count_removed);
422 size_t new_entry_count = entry_indices.size();
423 // Calculate the new capacity; multiply by 2 to allow room for metadata growth
424 size_t entry_capacity = (2 * new_entry_count);
425 size_t data_capacity = (2 * new_data_count);
426
427 // Allocate a new buffer with the smaller size
428 camera_metadata_t* orig_metadata = metadata_;
429 metadata_ = allocate_camera_metadata(entry_capacity, data_capacity);
430 if (metadata_ == nullptr) {
431 ALOGE("%s: Can't allocate new metadata buffer", __FUNCTION__);
432 metadata_ = orig_metadata;
433 return NO_MEMORY;
434 }
435
436 IF_ALOGV() {
437 ALOGV(
438 "%s: data capacity [%zu --> %zu], data count [%zu --> %zu], entry "
439 "capacity: [%zu --> %zu] entry count: [%zu --> %zu]",
440 __FUNCTION__, get_camera_metadata_data_capacity(orig_metadata),
441 data_capacity, data_count, new_data_count,
442 get_camera_metadata_entry_capacity(orig_metadata), entry_capacity,
443 entry_count, new_entry_count);
444 }
445
446 // Loop through the original metadata buffer and add all to the new buffer,
447 // except for those indices which were removed
448 for (size_t entry_index : entry_indices) {
449 res = CopyEntry(orig_metadata, metadata_, entry_index);
450 if (res != OK) {
451 ALOGE("%s: Error adding entry at index %zu failed: %s %d", __FUNCTION__,
452 entry_index, strerror(-res), res);
453 free_camera_metadata(metadata_);
454 metadata_ = orig_metadata;
455 return res;
456 }
457 }
458
459 free_camera_metadata(orig_metadata);
460 return OK;
461 }
462
Erase(uint32_t tag)463 status_t HalCameraMetadata::Erase(uint32_t tag) {
464 std::unique_lock<std::mutex> lock(metadata_lock_);
465 camera_metadata_entry_t entry;
466 status_t res = find_camera_metadata_entry(metadata_, tag, &entry);
467 if (res == NAME_NOT_FOUND) {
468 return OK;
469 } else if (res != OK) {
470 ALOGE("%s: Error finding entry (0x%x): %s %d", __FUNCTION__, tag,
471 strerror(-res), res);
472 return res;
473 }
474
475 res = delete_camera_metadata_entry(metadata_, entry.index);
476 if (res != OK) {
477 ALOGE("%s: Error deleting entry (0x%x): %s %d", __FUNCTION__, tag,
478 strerror(-res), res);
479 }
480 return res;
481 }
482
PrintData(const uint8_t * data,int32_t type,int32_t count,uint32_t indentation)483 void HalCameraMetadata::PrintData(const uint8_t* data, int32_t type,
484 int32_t count, uint32_t indentation) {
485 const uint32_t kDumpSizePerLine = 100;
486 static int32_t values_per_line[NUM_TYPES] = {
487 [TYPE_BYTE] = 16, [TYPE_INT32] = 4, [TYPE_FLOAT] = 8,
488 [TYPE_INT64] = 2, [TYPE_DOUBLE] = 4, [TYPE_RATIONAL] = 2,
489 };
490 int32_t max_type_count = sizeof(values_per_line) / sizeof(int32_t);
491 if (type >= max_type_count) {
492 ALOGE("%s: unsupported type: %d", __FUNCTION__, type);
493 return;
494 }
495 size_t type_size = camera_metadata_type_size[type];
496 char string[kDumpSizePerLine];
497 uint32_t string_offset;
498 int32_t lines = count / values_per_line[type];
499 if (count % values_per_line[type] != 0) {
500 lines++;
501 }
502
503 int32_t index = 0;
504 int32_t j = 0, k = 0;
505 for (j = 0; j < lines; j++) {
506 string_offset = 0;
507 string_offset +=
508 snprintf(&string[string_offset], (sizeof(string) - string_offset),
509 "%*s[ ", indentation + 4, "");
510 for (k = 0; k < values_per_line[type] && count > 0;
511 k++, count--, index += type_size) {
512 switch (type) {
513 case TYPE_BYTE: {
514 string_offset +=
515 snprintf(&string[string_offset], (sizeof(string) - string_offset),
516 "%hhu ", *(data + index));
517 break;
518 }
519 case TYPE_INT32: {
520 string_offset +=
521 snprintf(&string[string_offset], (sizeof(string) - string_offset),
522 "%d ", *reinterpret_cast<const int32_t*>(data + index));
523 break;
524 }
525 case TYPE_FLOAT: {
526 string_offset +=
527 snprintf(&string[string_offset], (sizeof(string) - string_offset),
528 "%0.8f ", *reinterpret_cast<const float*>(data + index));
529 break;
530 }
531 case TYPE_INT64: {
532 string_offset += snprintf(
533 &string[string_offset], (sizeof(string) - string_offset),
534 "%" PRId64 " ", *reinterpret_cast<const int64_t*>(data + index));
535 break;
536 }
537 case TYPE_DOUBLE: {
538 string_offset += snprintf(
539 &string[string_offset], (sizeof(string) - string_offset),
540 "%0.8f ", *reinterpret_cast<const double*>(data + index));
541 break;
542 }
543 case TYPE_RATIONAL: {
544 int32_t numerator = *(int32_t*)(data + index);
545 int32_t denominator = *(int32_t*)(data + index + 4);
546 string_offset +=
547 snprintf(&string[string_offset], (sizeof(string) - string_offset),
548 "(%d / %d) ", numerator, denominator);
549 break;
550 }
551 default: { break; }
552 }
553 }
554 string_offset +=
555 snprintf(&string[string_offset], (sizeof(string) - string_offset), "]");
556 ALOGI("%s:%s", __FUNCTION__, string);
557 }
558 }
559
Dump(int32_t fd,MetadataDumpVerbosity verbosity,uint32_t indentation) const560 void HalCameraMetadata::Dump(int32_t fd, MetadataDumpVerbosity verbosity,
561 uint32_t indentation) const {
562 std::unique_lock<std::mutex> lock(metadata_lock_);
563 if (fd >= 0) {
564 dump_indented_camera_metadata(metadata_, fd, static_cast<int>(verbosity),
565 indentation);
566 } else {
567 if (metadata_ == nullptr) {
568 ALOGE("%s: metadata_ is nullptr", __FUNCTION__);
569 return;
570 }
571 size_t entry_count = get_camera_metadata_entry_count(metadata_);
572 for (uint32_t i = 0; i < entry_count; i++) {
573 camera_metadata_ro_entry_t entry;
574 status_t res = get_camera_metadata_ro_entry(metadata_, i, &entry);
575 if (res != OK) {
576 ALOGE("%s: get_camera_metadata_ro_entry (%d) fail", __FUNCTION__, i);
577 continue;
578 }
579 const char *tag_name, *tag_section;
580 tag_section = get_local_camera_metadata_section_name(entry.tag, metadata_);
581 if (tag_section == nullptr) {
582 tag_section = "unknownSection";
583 }
584 tag_name = get_local_camera_metadata_tag_name(entry.tag, metadata_);
585 if (tag_name == nullptr) {
586 tag_name = "unknownTag";
587 }
588 const char* type_name;
589 if (entry.type >= NUM_TYPES) {
590 type_name = "unknown";
591 } else {
592 type_name = camera_metadata_type_names[entry.type];
593 }
594 ALOGI("%s: (%d) %s.%s (%05x): %s[%zu] ", __FUNCTION__, i, tag_section,
595 tag_name, entry.tag, type_name, entry.count);
596
597 if (verbosity < MetadataDumpVerbosity::kTagEntryWith16Data) {
598 continue;
599 }
600
601 if (entry.type >= NUM_TYPES) {
602 continue;
603 }
604 const uint8_t* data = entry.data.u8;
605
606 int32_t count = entry.count;
607 if (verbosity < MetadataDumpVerbosity::kAllInformation && count > 16) {
608 count = 16;
609 }
610 PrintData(data, entry.type, count, indentation);
611 }
612 }
613 }
614
Append(std::unique_ptr<HalCameraMetadata> hal_metadata)615 status_t HalCameraMetadata::Append(
616 std::unique_ptr<HalCameraMetadata> hal_metadata) {
617 if (hal_metadata == nullptr) {
618 ALOGE("%s: hal_metadata is nullptr", __FUNCTION__);
619 return BAD_VALUE;
620 }
621
622 return Append(hal_metadata->ReleaseCameraMetadata());
623 }
624
Append(camera_metadata_t * metadata)625 status_t HalCameraMetadata::Append(camera_metadata_t* metadata) {
626 if (metadata == nullptr) {
627 ALOGE("%s: metadata is nullptr", __FUNCTION__);
628 return BAD_VALUE;
629 }
630 std::unique_lock<std::mutex> lock(metadata_lock_);
631 size_t extra_entries = get_camera_metadata_entry_count(metadata);
632 size_t extra_data = get_camera_metadata_data_count(metadata);
633 status_t res = ResizeIfNeeded(extra_entries, extra_data);
634 if (res != OK) {
635 ALOGE("%s: Resize fail", __FUNCTION__);
636 return res;
637 }
638
639 return append_camera_metadata(metadata_, metadata);
640 }
641
GetEntryCount() const642 size_t HalCameraMetadata::GetEntryCount() const {
643 std::unique_lock<std::mutex> lock(metadata_lock_);
644 return (metadata_ == nullptr) ? 0 : get_camera_metadata_entry_count(metadata_);
645 }
646
CopyEntry(const camera_metadata_t * src,camera_metadata_t * dest,size_t entry_index) const647 status_t HalCameraMetadata::CopyEntry(const camera_metadata_t* src,
648 camera_metadata_t* dest,
649 size_t entry_index) const {
650 if (src == nullptr || dest == nullptr) {
651 ALOGE("%s: src (%p) or dest(%p) is nullptr", __FUNCTION__, src, dest);
652 return BAD_VALUE;
653 }
654
655 camera_metadata_ro_entry entry;
656 status_t res = get_camera_metadata_ro_entry(src, entry_index, &entry);
657 if (res != OK) {
658 ALOGE("%s: failed to get entry index %zu", __FUNCTION__, entry_index);
659 return res;
660 }
661
662 res = add_camera_metadata_entry(dest, entry.tag, entry.data.u8, entry.count);
663 if (res != OK) {
664 ALOGE("%s: failed to add entry index %zu", __FUNCTION__, entry_index);
665 return res;
666 }
667
668 return OK;
669 }
670 } // namespace google_camera_hal
671 } // namespace android