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(const camera_metadata_t * metadata)625 status_t HalCameraMetadata::Append(const 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