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 #include <inttypes.h>
18 #include <system/camera_metadata.h>
19 #include <camera_metadata_hidden.h>
20 
21 #define LOG_TAG "camera_metadata"
22 #include <cutils/log.h>
23 #include <assert.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 
28 #define OK         0
29 #define ERROR      1
30 #define NOT_FOUND -ENOENT
31 
32 #define ALIGN_TO(val, alignment) \
33     (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
34 
35 /**
36  * A single metadata entry, storing an array of values of a given type. If the
37  * array is no larger than 4 bytes in size, it is stored in the data.value[]
38  * array; otherwise, it can found in the parent's data array at index
39  * data.offset.
40  */
41 #define ENTRY_ALIGNMENT ((size_t) 4)
42 typedef struct camera_metadata_buffer_entry {
43     uint32_t tag;
44     uint32_t count;
45     union {
46         uint32_t offset;
47         uint8_t  value[4];
48     } data;
49     uint8_t  type;
50     uint8_t  reserved[3];
51 } camera_metadata_buffer_entry_t;
52 
53 typedef uint32_t metadata_uptrdiff_t;
54 typedef uint32_t metadata_size_t;
55 
56 /**
57  * A packet of metadata. This is a list of entries, each of which may point to
58  * its values stored at an offset in data.
59  *
60  * It is assumed by the utility functions that the memory layout of the packet
61  * is as follows:
62  *
63  *   |-----------------------------------------------|
64  *   | camera_metadata_t                             |
65  *   |                                               |
66  *   |-----------------------------------------------|
67  *   | reserved for future expansion                 |
68  *   |-----------------------------------------------|
69  *   | camera_metadata_buffer_entry_t #0             |
70  *   |-----------------------------------------------|
71  *   | ....                                          |
72  *   |-----------------------------------------------|
73  *   | camera_metadata_buffer_entry_t #entry_count-1 |
74  *   |-----------------------------------------------|
75  *   | free space for                                |
76  *   | (entry_capacity-entry_count) entries          |
77  *   |-----------------------------------------------|
78  *   | start of camera_metadata.data                 |
79  *   |                                               |
80  *   |-----------------------------------------------|
81  *   | free space for                                |
82  *   | (data_capacity-data_count) bytes              |
83  *   |-----------------------------------------------|
84  *
85  * With the total length of the whole packet being camera_metadata.size bytes.
86  *
87  * In short, the entries and data are contiguous in memory after the metadata
88  * header.
89  */
90 #define METADATA_ALIGNMENT ((size_t) 4)
91 struct camera_metadata {
92     metadata_size_t          size;
93     uint32_t                 version;
94     uint32_t                 flags;
95     metadata_size_t          entry_count;
96     metadata_size_t          entry_capacity;
97     metadata_uptrdiff_t      entries_start; // Offset from camera_metadata
98     metadata_size_t          data_count;
99     metadata_size_t          data_capacity;
100     metadata_uptrdiff_t      data_start; // Offset from camera_metadata
101     uint8_t                  reserved[];
102 };
103 
104 /**
105  * A datum of metadata. This corresponds to camera_metadata_entry_t::data
106  * with the difference that each element is not a pointer. We need to have a
107  * non-pointer type description in order to figure out the largest alignment
108  * requirement for data (DATA_ALIGNMENT).
109  */
110 #define DATA_ALIGNMENT ((size_t) 8)
111 typedef union camera_metadata_data {
112     uint8_t u8;
113     int32_t i32;
114     float   f;
115     int64_t i64;
116     double  d;
117     camera_metadata_rational_t r;
118 } camera_metadata_data_t;
119 
120 /**
121  * The preferred alignment of a packet of camera metadata. In general,
122  * this is the lowest common multiple of the constituents of a metadata
123  * package, i.e, of DATA_ALIGNMENT and ENTRY_ALIGNMENT.
124  */
125 #define MAX_ALIGNMENT(A, B) (((A) > (B)) ? (A) : (B))
126 #define METADATA_PACKET_ALIGNMENT \
127     MAX_ALIGNMENT(MAX_ALIGNMENT(DATA_ALIGNMENT, METADATA_ALIGNMENT), ENTRY_ALIGNMENT);
128 
129 /** Versioning information */
130 #define CURRENT_METADATA_VERSION 1
131 
132 /** Flag definitions */
133 #define FLAG_SORTED 0x00000001
134 
135 /** Tag information */
136 
137 typedef struct tag_info {
138     const char *tag_name;
139     uint8_t     tag_type;
140 } tag_info_t;
141 
142 #include "camera_metadata_tag_info.c"
143 
144 const size_t camera_metadata_type_size[NUM_TYPES] = {
145     [TYPE_BYTE]     = sizeof(uint8_t),
146     [TYPE_INT32]    = sizeof(int32_t),
147     [TYPE_FLOAT]    = sizeof(float),
148     [TYPE_INT64]    = sizeof(int64_t),
149     [TYPE_DOUBLE]   = sizeof(double),
150     [TYPE_RATIONAL] = sizeof(camera_metadata_rational_t)
151 };
152 
153 const char *camera_metadata_type_names[NUM_TYPES] = {
154     [TYPE_BYTE]     = "byte",
155     [TYPE_INT32]    = "int32",
156     [TYPE_FLOAT]    = "float",
157     [TYPE_INT64]    = "int64",
158     [TYPE_DOUBLE]   = "double",
159     [TYPE_RATIONAL] = "rational"
160 };
161 
get_entries(const camera_metadata_t * metadata)162 static camera_metadata_buffer_entry_t *get_entries(
163         const camera_metadata_t *metadata) {
164     return (camera_metadata_buffer_entry_t*)
165             ((uint8_t*)metadata + metadata->entries_start);
166 }
167 
get_data(const camera_metadata_t * metadata)168 static uint8_t *get_data(const camera_metadata_t *metadata) {
169     return (uint8_t*)metadata + metadata->data_start;
170 }
171 
get_camera_metadata_alignment()172 size_t get_camera_metadata_alignment() {
173     return METADATA_PACKET_ALIGNMENT;
174 }
175 
allocate_copy_camera_metadata_checked(const camera_metadata_t * src,size_t src_size)176 camera_metadata_t *allocate_copy_camera_metadata_checked(
177         const camera_metadata_t *src,
178         size_t src_size) {
179 
180     if (src == NULL) {
181         return NULL;
182     }
183 
184     void *buffer = malloc(src_size);
185     memcpy(buffer, src, src_size);
186 
187     camera_metadata_t *metadata = (camera_metadata_t*) buffer;
188     if (validate_camera_metadata_structure(metadata, &src_size) != OK) {
189         free(buffer);
190         return NULL;
191     }
192 
193     return metadata;
194 }
195 
allocate_camera_metadata(size_t entry_capacity,size_t data_capacity)196 camera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
197                                             size_t data_capacity) {
198 
199     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
200                                                           data_capacity);
201     void *buffer = malloc(memory_needed);
202     return place_camera_metadata(buffer, memory_needed,
203                                  entry_capacity,
204                                  data_capacity);
205 }
206 
place_camera_metadata(void * dst,size_t dst_size,size_t entry_capacity,size_t data_capacity)207 camera_metadata_t *place_camera_metadata(void *dst,
208                                          size_t dst_size,
209                                          size_t entry_capacity,
210                                          size_t data_capacity) {
211     if (dst == NULL) return NULL;
212 
213     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
214                                                           data_capacity);
215     if (memory_needed > dst_size) return NULL;
216 
217     camera_metadata_t *metadata = (camera_metadata_t*)dst;
218     metadata->version = CURRENT_METADATA_VERSION;
219     metadata->flags = 0;
220     metadata->entry_count = 0;
221     metadata->entry_capacity = entry_capacity;
222     metadata->entries_start =
223             ALIGN_TO(sizeof(camera_metadata_t), ENTRY_ALIGNMENT);
224     metadata->data_count = 0;
225     metadata->data_capacity = data_capacity;
226     metadata->size = memory_needed;
227     size_t data_unaligned = (uint8_t*)(get_entries(metadata) +
228             metadata->entry_capacity) - (uint8_t*)metadata;
229     metadata->data_start = ALIGN_TO(data_unaligned, DATA_ALIGNMENT);
230 
231     assert(validate_camera_metadata_structure(metadata, NULL) == OK);
232     return metadata;
233 }
free_camera_metadata(camera_metadata_t * metadata)234 void free_camera_metadata(camera_metadata_t *metadata) {
235     free(metadata);
236 }
237 
calculate_camera_metadata_size(size_t entry_count,size_t data_count)238 size_t calculate_camera_metadata_size(size_t entry_count,
239                                       size_t data_count) {
240     size_t memory_needed = sizeof(camera_metadata_t);
241     // Start entry list at aligned boundary
242     memory_needed = ALIGN_TO(memory_needed, ENTRY_ALIGNMENT);
243     memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
244     // Start buffer list at aligned boundary
245     memory_needed = ALIGN_TO(memory_needed, DATA_ALIGNMENT);
246     memory_needed += sizeof(uint8_t[data_count]);
247     return memory_needed;
248 }
249 
get_camera_metadata_size(const camera_metadata_t * metadata)250 size_t get_camera_metadata_size(const camera_metadata_t *metadata) {
251     if (metadata == NULL) return ERROR;
252 
253     return metadata->size;
254 }
255 
get_camera_metadata_compact_size(const camera_metadata_t * metadata)256 size_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
257     if (metadata == NULL) return ERROR;
258 
259     return calculate_camera_metadata_size(metadata->entry_count,
260                                           metadata->data_count);
261 }
262 
get_camera_metadata_entry_count(const camera_metadata_t * metadata)263 size_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
264     return metadata->entry_count;
265 }
266 
get_camera_metadata_entry_capacity(const camera_metadata_t * metadata)267 size_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
268     return metadata->entry_capacity;
269 }
270 
get_camera_metadata_data_count(const camera_metadata_t * metadata)271 size_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
272     return metadata->data_count;
273 }
274 
get_camera_metadata_data_capacity(const camera_metadata_t * metadata)275 size_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
276     return metadata->data_capacity;
277 }
278 
copy_camera_metadata(void * dst,size_t dst_size,const camera_metadata_t * src)279 camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
280         const camera_metadata_t *src) {
281     size_t memory_needed = get_camera_metadata_compact_size(src);
282 
283     if (dst == NULL) return NULL;
284     if (dst_size < memory_needed) return NULL;
285 
286     camera_metadata_t *metadata =
287         place_camera_metadata(dst, dst_size, src->entry_count, src->data_count);
288 
289     metadata->flags = src->flags;
290     metadata->entry_count = src->entry_count;
291     metadata->data_count = src->data_count;
292 
293     memcpy(get_entries(metadata), get_entries(src),
294             sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
295     memcpy(get_data(metadata), get_data(src),
296             sizeof(uint8_t[metadata->data_count]));
297 
298     assert(validate_camera_metadata_structure(metadata, NULL) == OK);
299     return metadata;
300 }
301 
validate_camera_metadata_structure(const camera_metadata_t * metadata,const size_t * expected_size)302 int validate_camera_metadata_structure(const camera_metadata_t *metadata,
303                                        const size_t *expected_size) {
304 
305     if (metadata == NULL) {
306         ALOGE("%s: metadata is null!", __FUNCTION__);
307         return ERROR;
308     }
309 
310     // Check that the metadata pointer is well-aligned first.
311     {
312         static const struct {
313             const char *name;
314             size_t alignment;
315         } alignments[] = {
316             {
317                 .name = "camera_metadata",
318                 .alignment = METADATA_ALIGNMENT
319             },
320             {
321                 .name = "camera_metadata_buffer_entry",
322                 .alignment = ENTRY_ALIGNMENT
323             },
324             {
325                 .name = "camera_metadata_data",
326                 .alignment = DATA_ALIGNMENT
327             },
328         };
329 
330         for (size_t i = 0; i < sizeof(alignments)/sizeof(alignments[0]); ++i) {
331             uintptr_t aligned_ptr = ALIGN_TO(metadata, alignments[i].alignment);
332 
333             if ((uintptr_t)metadata != aligned_ptr) {
334                 ALOGE("%s: Metadata pointer is not aligned (actual %p, "
335                       "expected %p) to type %s",
336                       __FUNCTION__, metadata,
337                       (void*)aligned_ptr, alignments[i].name);
338                 return ERROR;
339             }
340         }
341     }
342 
343     /**
344      * Check that the metadata contents are correct
345      */
346 
347     if (expected_size != NULL && metadata->size > *expected_size) {
348         ALOGE("%s: Metadata size (%" PRIu32 ") should be <= expected size (%zu)",
349               __FUNCTION__, metadata->size, *expected_size);
350         return ERROR;
351     }
352 
353     if (metadata->entry_count > metadata->entry_capacity) {
354         ALOGE("%s: Entry count (%" PRIu32 ") should be <= entry capacity "
355               "(%" PRIu32 ")",
356               __FUNCTION__, metadata->entry_count, metadata->entry_capacity);
357         return ERROR;
358     }
359 
360     const metadata_uptrdiff_t entries_end =
361         metadata->entries_start + metadata->entry_capacity;
362     if (entries_end < metadata->entries_start || // overflow check
363         entries_end > metadata->data_start) {
364 
365         ALOGE("%s: Entry start + capacity (%" PRIu32 ") should be <= data start "
366               "(%" PRIu32 ")",
367                __FUNCTION__,
368               (metadata->entries_start + metadata->entry_capacity),
369               metadata->data_start);
370         return ERROR;
371     }
372 
373     const metadata_uptrdiff_t data_end =
374         metadata->data_start + metadata->data_capacity;
375     if (data_end < metadata->data_start || // overflow check
376         data_end > metadata->size) {
377 
378         ALOGE("%s: Data start + capacity (%" PRIu32 ") should be <= total size "
379               "(%" PRIu32 ")",
380                __FUNCTION__,
381               (metadata->data_start + metadata->data_capacity),
382               metadata->size);
383         return ERROR;
384     }
385 
386     // Validate each entry
387     const metadata_size_t entry_count = metadata->entry_count;
388     camera_metadata_buffer_entry_t *entries = get_entries(metadata);
389 
390     for (size_t i = 0; i < entry_count; ++i) {
391 
392         if ((uintptr_t)&entries[i] != ALIGN_TO(&entries[i], ENTRY_ALIGNMENT)) {
393             ALOGE("%s: Entry index %zu had bad alignment (address %p),"
394                   " expected alignment %zu",
395                   __FUNCTION__, i, &entries[i], ENTRY_ALIGNMENT);
396             return ERROR;
397         }
398 
399         camera_metadata_buffer_entry_t entry = entries[i];
400 
401         if (entry.type >= NUM_TYPES) {
402             ALOGE("%s: Entry index %zu had a bad type %d",
403                   __FUNCTION__, i, entry.type);
404             return ERROR;
405         }
406 
407         // TODO: fix vendor_tag_ops across processes so we don't need to special
408         //       case vendor-specific tags
409         uint32_t tag_section = entry.tag >> 16;
410         int tag_type = get_camera_metadata_tag_type(entry.tag);
411         if (tag_type != (int)entry.type && tag_section < VENDOR_SECTION) {
412             ALOGE("%s: Entry index %zu had tag type %d, but the type was %d",
413                   __FUNCTION__, i, tag_type, entry.type);
414             return ERROR;
415         }
416 
417         size_t data_size =
418                 calculate_camera_metadata_entry_data_size(entry.type,
419                                                           entry.count);
420 
421         if (data_size != 0) {
422             camera_metadata_data_t *data =
423                     (camera_metadata_data_t*) (get_data(metadata) +
424                                                entry.data.offset);
425 
426             if ((uintptr_t)data != ALIGN_TO(data, DATA_ALIGNMENT)) {
427                 ALOGE("%s: Entry index %zu had bad data alignment (address %p),"
428                       " expected align %zu, (tag name %s, data size %zu)",
429                       __FUNCTION__, i, data, DATA_ALIGNMENT,
430                       get_camera_metadata_tag_name(entry.tag) ?: "unknown",
431                       data_size);
432                 return ERROR;
433             }
434 
435             size_t data_entry_end = entry.data.offset + data_size;
436             if (data_entry_end < entry.data.offset || // overflow check
437                 data_entry_end > metadata->data_capacity) {
438 
439                 ALOGE("%s: Entry index %zu data ends (%zu) beyond the capacity "
440                       "%" PRIu32, __FUNCTION__, i, data_entry_end,
441                       metadata->data_capacity);
442                 return ERROR;
443             }
444 
445         } else if (entry.count == 0) {
446             if (entry.data.offset != 0) {
447                 ALOGE("%s: Entry index %zu had 0 items, but offset was non-0 "
448                      "(%" PRIu32 "), tag name: %s", __FUNCTION__, i, entry.data.offset,
449                         get_camera_metadata_tag_name(entry.tag) ?: "unknown");
450                 return ERROR;
451             }
452         } // else data stored inline, so we look at value which can be anything.
453     }
454 
455     return OK;
456 }
457 
append_camera_metadata(camera_metadata_t * dst,const camera_metadata_t * src)458 int append_camera_metadata(camera_metadata_t *dst,
459         const camera_metadata_t *src) {
460     if (dst == NULL || src == NULL ) return ERROR;
461 
462     if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
463     if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
464 
465     memcpy(get_entries(dst) + dst->entry_count, get_entries(src),
466             sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
467     memcpy(get_data(dst) + dst->data_count, get_data(src),
468             sizeof(uint8_t[src->data_count]));
469     if (dst->data_count != 0) {
470         camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
471         for (size_t i = 0; i < src->entry_count; i++, entry++) {
472             if ( calculate_camera_metadata_entry_data_size(entry->type,
473                             entry->count) > 0 ) {
474                 entry->data.offset += dst->data_count;
475             }
476         }
477     }
478     if (dst->entry_count == 0) {
479         // Appending onto empty buffer, keep sorted state
480         dst->flags |= src->flags & FLAG_SORTED;
481     } else if (src->entry_count != 0) {
482         // Both src, dst are nonempty, cannot assume sort remains
483         dst->flags &= ~FLAG_SORTED;
484     } else {
485         // Src is empty, keep dst sorted state
486     }
487     dst->entry_count += src->entry_count;
488     dst->data_count += src->data_count;
489 
490     assert(validate_camera_metadata_structure(dst, NULL) == OK);
491     return OK;
492 }
493 
clone_camera_metadata(const camera_metadata_t * src)494 camera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) {
495     int res;
496     if (src == NULL) return NULL;
497     camera_metadata_t *clone = allocate_camera_metadata(
498         get_camera_metadata_entry_count(src),
499         get_camera_metadata_data_count(src));
500     if (clone != NULL) {
501         res = append_camera_metadata(clone, src);
502         if (res != OK) {
503             free_camera_metadata(clone);
504             clone = NULL;
505         }
506     }
507     assert(validate_camera_metadata_structure(clone, NULL) == OK);
508     return clone;
509 }
510 
calculate_camera_metadata_entry_data_size(uint8_t type,size_t data_count)511 size_t calculate_camera_metadata_entry_data_size(uint8_t type,
512         size_t data_count) {
513     if (type >= NUM_TYPES) return 0;
514     size_t data_bytes = data_count *
515             camera_metadata_type_size[type];
516     return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
517 }
518 
add_camera_metadata_entry_raw(camera_metadata_t * dst,uint32_t tag,uint8_t type,const void * data,size_t data_count)519 static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
520         uint32_t tag,
521         uint8_t  type,
522         const void *data,
523         size_t data_count) {
524 
525     if (dst == NULL) return ERROR;
526     if (dst->entry_count == dst->entry_capacity) return ERROR;
527     if (data == NULL) return ERROR;
528 
529     size_t data_bytes =
530             calculate_camera_metadata_entry_data_size(type, data_count);
531     if (data_bytes + dst->data_count > dst->data_capacity) return ERROR;
532 
533     size_t data_payload_bytes =
534             data_count * camera_metadata_type_size[type];
535     camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
536     memset(entry, 0, sizeof(camera_metadata_buffer_entry_t));
537     entry->tag = tag;
538     entry->type = type;
539     entry->count = data_count;
540 
541     if (data_bytes == 0) {
542         memcpy(entry->data.value, data,
543                 data_payload_bytes);
544     } else {
545         entry->data.offset = dst->data_count;
546         memcpy(get_data(dst) + entry->data.offset, data,
547                 data_payload_bytes);
548         dst->data_count += data_bytes;
549     }
550     dst->entry_count++;
551     dst->flags &= ~FLAG_SORTED;
552     assert(validate_camera_metadata_structure(dst, NULL) == OK);
553     return OK;
554 }
555 
add_camera_metadata_entry(camera_metadata_t * dst,uint32_t tag,const void * data,size_t data_count)556 int add_camera_metadata_entry(camera_metadata_t *dst,
557         uint32_t tag,
558         const void *data,
559         size_t data_count) {
560 
561     int type = get_camera_metadata_tag_type(tag);
562     if (type == -1) {
563         ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
564         return ERROR;
565     }
566 
567     return add_camera_metadata_entry_raw(dst,
568             tag,
569             type,
570             data,
571             data_count);
572 }
573 
compare_entry_tags(const void * p1,const void * p2)574 static int compare_entry_tags(const void *p1, const void *p2) {
575     uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
576     uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
577     return  tag1 < tag2 ? -1 :
578             tag1 == tag2 ? 0 :
579             1;
580 }
581 
sort_camera_metadata(camera_metadata_t * dst)582 int sort_camera_metadata(camera_metadata_t *dst) {
583     if (dst == NULL) return ERROR;
584     if (dst->flags & FLAG_SORTED) return OK;
585 
586     qsort(get_entries(dst), dst->entry_count,
587             sizeof(camera_metadata_buffer_entry_t),
588             compare_entry_tags);
589     dst->flags |= FLAG_SORTED;
590 
591     assert(validate_camera_metadata_structure(dst, NULL) == OK);
592     return OK;
593 }
594 
get_camera_metadata_entry(camera_metadata_t * src,size_t index,camera_metadata_entry_t * entry)595 int get_camera_metadata_entry(camera_metadata_t *src,
596         size_t index,
597         camera_metadata_entry_t *entry) {
598     if (src == NULL || entry == NULL) return ERROR;
599     if (index >= src->entry_count) return ERROR;
600 
601     camera_metadata_buffer_entry_t *buffer_entry = get_entries(src) + index;
602 
603     entry->index = index;
604     entry->tag = buffer_entry->tag;
605     entry->type = buffer_entry->type;
606     entry->count = buffer_entry->count;
607     if (buffer_entry->count *
608             camera_metadata_type_size[buffer_entry->type] > 4) {
609         entry->data.u8 = get_data(src) + buffer_entry->data.offset;
610     } else {
611         entry->data.u8 = buffer_entry->data.value;
612     }
613     return OK;
614 }
615 
get_camera_metadata_ro_entry(const camera_metadata_t * src,size_t index,camera_metadata_ro_entry_t * entry)616 int get_camera_metadata_ro_entry(const camera_metadata_t *src,
617         size_t index,
618         camera_metadata_ro_entry_t *entry) {
619     return get_camera_metadata_entry((camera_metadata_t*)src, index,
620             (camera_metadata_entry_t*)entry);
621 }
622 
find_camera_metadata_entry(camera_metadata_t * src,uint32_t tag,camera_metadata_entry_t * entry)623 int find_camera_metadata_entry(camera_metadata_t *src,
624         uint32_t tag,
625         camera_metadata_entry_t *entry) {
626     if (src == NULL) return ERROR;
627 
628     uint32_t index;
629     if (src->flags & FLAG_SORTED) {
630         // Sorted entries, do a binary search
631         camera_metadata_buffer_entry_t *search_entry = NULL;
632         camera_metadata_buffer_entry_t key;
633         key.tag = tag;
634         search_entry = bsearch(&key,
635                 get_entries(src),
636                 src->entry_count,
637                 sizeof(camera_metadata_buffer_entry_t),
638                 compare_entry_tags);
639         if (search_entry == NULL) return NOT_FOUND;
640         index = search_entry - get_entries(src);
641     } else {
642         // Not sorted, linear search
643         camera_metadata_buffer_entry_t *search_entry = get_entries(src);
644         for (index = 0; index < src->entry_count; index++, search_entry++) {
645             if (search_entry->tag == tag) {
646                 break;
647             }
648         }
649         if (index == src->entry_count) return NOT_FOUND;
650     }
651 
652     return get_camera_metadata_entry(src, index,
653             entry);
654 }
655 
find_camera_metadata_ro_entry(const camera_metadata_t * src,uint32_t tag,camera_metadata_ro_entry_t * entry)656 int find_camera_metadata_ro_entry(const camera_metadata_t *src,
657         uint32_t tag,
658         camera_metadata_ro_entry_t *entry) {
659     return find_camera_metadata_entry((camera_metadata_t*)src, tag,
660             (camera_metadata_entry_t*)entry);
661 }
662 
663 
delete_camera_metadata_entry(camera_metadata_t * dst,size_t index)664 int delete_camera_metadata_entry(camera_metadata_t *dst,
665         size_t index) {
666     if (dst == NULL) return ERROR;
667     if (index >= dst->entry_count) return ERROR;
668 
669     camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
670     size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
671             entry->count);
672 
673     if (data_bytes > 0) {
674         // Shift data buffer to overwrite deleted data
675         uint8_t *start = get_data(dst) + entry->data.offset;
676         uint8_t *end = start + data_bytes;
677         size_t length = dst->data_count - entry->data.offset - data_bytes;
678         memmove(start, end, length);
679 
680         // Update all entry indices to account for shift
681         camera_metadata_buffer_entry_t *e = get_entries(dst);
682         size_t i;
683         for (i = 0; i < dst->entry_count; i++) {
684             if (calculate_camera_metadata_entry_data_size(
685                     e->type, e->count) > 0 &&
686                     e->data.offset > entry->data.offset) {
687                 e->data.offset -= data_bytes;
688             }
689             ++e;
690         }
691         dst->data_count -= data_bytes;
692     }
693     // Shift entry array
694     memmove(entry, entry + 1,
695             sizeof(camera_metadata_buffer_entry_t) *
696             (dst->entry_count - index - 1) );
697     dst->entry_count -= 1;
698 
699     assert(validate_camera_metadata_structure(dst, NULL) == OK);
700     return OK;
701 }
702 
update_camera_metadata_entry(camera_metadata_t * dst,size_t index,const void * data,size_t data_count,camera_metadata_entry_t * updated_entry)703 int update_camera_metadata_entry(camera_metadata_t *dst,
704         size_t index,
705         const void *data,
706         size_t data_count,
707         camera_metadata_entry_t *updated_entry) {
708     if (dst == NULL) return ERROR;
709     if (index >= dst->entry_count) return ERROR;
710 
711     camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
712 
713     size_t data_bytes =
714             calculate_camera_metadata_entry_data_size(entry->type,
715                     data_count);
716     size_t data_payload_bytes =
717             data_count * camera_metadata_type_size[entry->type];
718 
719     size_t entry_bytes =
720             calculate_camera_metadata_entry_data_size(entry->type,
721                     entry->count);
722     if (data_bytes != entry_bytes) {
723         // May need to shift/add to data array
724         if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
725             // No room
726             return ERROR;
727         }
728         if (entry_bytes != 0) {
729             // Remove old data
730             uint8_t *start = get_data(dst) + entry->data.offset;
731             uint8_t *end = start + entry_bytes;
732             size_t length = dst->data_count - entry->data.offset - entry_bytes;
733             memmove(start, end, length);
734             dst->data_count -= entry_bytes;
735 
736             // Update all entry indices to account for shift
737             camera_metadata_buffer_entry_t *e = get_entries(dst);
738             size_t i;
739             for (i = 0; i < dst->entry_count; i++) {
740                 if (calculate_camera_metadata_entry_data_size(
741                         e->type, e->count) > 0 &&
742                         e->data.offset > entry->data.offset) {
743                     e->data.offset -= entry_bytes;
744                 }
745                 ++e;
746             }
747         }
748 
749         if (data_bytes != 0) {
750             // Append new data
751             entry->data.offset = dst->data_count;
752 
753             memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
754             dst->data_count += data_bytes;
755         }
756     } else if (data_bytes != 0) {
757         // data size unchanged, reuse same data location
758         memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
759     }
760 
761     if (data_bytes == 0) {
762         // Data fits into entry
763         memcpy(entry->data.value, data,
764                 data_payload_bytes);
765     }
766 
767     entry->count = data_count;
768 
769     if (updated_entry != NULL) {
770         get_camera_metadata_entry(dst,
771                 index,
772                 updated_entry);
773     }
774 
775     assert(validate_camera_metadata_structure(dst, NULL) == OK);
776     return OK;
777 }
778 
779 static const vendor_tag_ops_t *vendor_tag_ops = NULL;
780 
get_camera_metadata_section_name(uint32_t tag)781 const char *get_camera_metadata_section_name(uint32_t tag) {
782     uint32_t tag_section = tag >> 16;
783     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
784         return vendor_tag_ops->get_section_name(
785             vendor_tag_ops,
786             tag);
787     }
788     if (tag_section >= ANDROID_SECTION_COUNT) {
789         return NULL;
790     }
791     return camera_metadata_section_names[tag_section];
792 }
793 
get_camera_metadata_tag_name(uint32_t tag)794 const char *get_camera_metadata_tag_name(uint32_t tag) {
795     uint32_t tag_section = tag >> 16;
796     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
797         return vendor_tag_ops->get_tag_name(
798             vendor_tag_ops,
799             tag);
800     }
801     if (tag_section >= ANDROID_SECTION_COUNT ||
802         tag >= camera_metadata_section_bounds[tag_section][1] ) {
803         return NULL;
804     }
805     uint32_t tag_index = tag & 0xFFFF;
806     return tag_info[tag_section][tag_index].tag_name;
807 }
808 
get_camera_metadata_tag_type(uint32_t tag)809 int get_camera_metadata_tag_type(uint32_t tag) {
810     uint32_t tag_section = tag >> 16;
811     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
812         return vendor_tag_ops->get_tag_type(
813             vendor_tag_ops,
814             tag);
815     }
816     if (tag_section >= ANDROID_SECTION_COUNT ||
817             tag >= camera_metadata_section_bounds[tag_section][1] ) {
818         return -1;
819     }
820     uint32_t tag_index = tag & 0xFFFF;
821     return tag_info[tag_section][tag_index].tag_type;
822 }
823 
set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t * ops)824 int set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t* ops) {
825     // **DEPRECATED**
826     ALOGE("%s: This function has been deprecated", __FUNCTION__);
827     return ERROR;
828 }
829 
830 // Declared in system/media/private/camera/include/camera_metadata_hidden.h
set_camera_metadata_vendor_ops(const vendor_tag_ops_t * ops)831 int set_camera_metadata_vendor_ops(const vendor_tag_ops_t* ops) {
832     vendor_tag_ops = ops;
833     return OK;
834 }
835 
836 static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, int type,
837         int count,
838         int indentation);
839 
dump_camera_metadata(const camera_metadata_t * metadata,int fd,int verbosity)840 void dump_camera_metadata(const camera_metadata_t *metadata,
841         int fd,
842         int verbosity) {
843     dump_indented_camera_metadata(metadata, fd, verbosity, 0);
844 }
845 
dump_indented_camera_metadata(const camera_metadata_t * metadata,int fd,int verbosity,int indentation)846 void dump_indented_camera_metadata(const camera_metadata_t *metadata,
847         int fd,
848         int verbosity,
849         int indentation) {
850     if (metadata == NULL) {
851         dprintf(fd, "%*sDumping camera metadata array: Not allocated\n",
852                 indentation, "");
853         return;
854     }
855     unsigned int i;
856     dprintf(fd,
857             "%*sDumping camera metadata array: %" PRIu32 " / %" PRIu32 " entries, "
858             "%" PRIu32 " / %" PRIu32 " bytes of extra data.\n", indentation, "",
859             metadata->entry_count, metadata->entry_capacity,
860             metadata->data_count, metadata->data_capacity);
861     dprintf(fd, "%*sVersion: %d, Flags: %08x\n",
862             indentation + 2, "",
863             metadata->version, metadata->flags);
864     camera_metadata_buffer_entry_t *entry = get_entries(metadata);
865     for (i=0; i < metadata->entry_count; i++, entry++) {
866 
867         const char *tag_name, *tag_section;
868         tag_section = get_camera_metadata_section_name(entry->tag);
869         if (tag_section == NULL) {
870             tag_section = "unknownSection";
871         }
872         tag_name = get_camera_metadata_tag_name(entry->tag);
873         if (tag_name == NULL) {
874             tag_name = "unknownTag";
875         }
876         const char *type_name;
877         if (entry->type >= NUM_TYPES) {
878             type_name = "unknown";
879         } else {
880             type_name = camera_metadata_type_names[entry->type];
881         }
882         dprintf(fd, "%*s%s.%s (%05x): %s[%" PRIu32 "]\n",
883              indentation + 2, "",
884              tag_section,
885              tag_name,
886              entry->tag,
887              type_name,
888              entry->count);
889 
890         if (verbosity < 1) continue;
891 
892         if (entry->type >= NUM_TYPES) continue;
893 
894         size_t type_size = camera_metadata_type_size[entry->type];
895         uint8_t *data_ptr;
896         if ( type_size * entry->count > 4 ) {
897             if (entry->data.offset >= metadata->data_count) {
898                 ALOGE("%s: Malformed entry data offset: %" PRIu32 " (max %" PRIu32 ")",
899                         __FUNCTION__,
900                         entry->data.offset,
901                         metadata->data_count);
902                 continue;
903             }
904             data_ptr = get_data(metadata) + entry->data.offset;
905         } else {
906             data_ptr = entry->data.value;
907         }
908         int count = entry->count;
909         if (verbosity < 2 && count > 16) count = 16;
910 
911         print_data(fd, data_ptr, entry->tag, entry->type, count, indentation);
912     }
913 }
914 
print_data(int fd,const uint8_t * data_ptr,uint32_t tag,int type,int count,int indentation)915 static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag,
916         int type, int count, int indentation) {
917     static int values_per_line[NUM_TYPES] = {
918         [TYPE_BYTE]     = 16,
919         [TYPE_INT32]    = 4,
920         [TYPE_FLOAT]    = 8,
921         [TYPE_INT64]    = 2,
922         [TYPE_DOUBLE]   = 4,
923         [TYPE_RATIONAL] = 2,
924     };
925     size_t type_size = camera_metadata_type_size[type];
926     char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE];
927     uint32_t value;
928 
929     int lines = count / values_per_line[type];
930     if (count % values_per_line[type] != 0) lines++;
931 
932     int index = 0;
933     int j, k;
934     for (j = 0; j < lines; j++) {
935         dprintf(fd, "%*s[", indentation + 4, "");
936         for (k = 0;
937              k < values_per_line[type] && count > 0;
938              k++, count--, index += type_size) {
939 
940             switch (type) {
941                 case TYPE_BYTE:
942                     value = *(data_ptr + index);
943                     if (camera_metadata_enum_snprint(tag,
944                                                      value,
945                                                      value_string_tmp,
946                                                      sizeof(value_string_tmp))
947                         == OK) {
948                         dprintf(fd, "%s ", value_string_tmp);
949                     } else {
950                         dprintf(fd, "%hhu ",
951                                 *(data_ptr + index));
952                     }
953                     break;
954                 case TYPE_INT32:
955                     value =
956                             *(int32_t*)(data_ptr + index);
957                     if (camera_metadata_enum_snprint(tag,
958                                                      value,
959                                                      value_string_tmp,
960                                                      sizeof(value_string_tmp))
961                         == OK) {
962                         dprintf(fd, "%s ", value_string_tmp);
963                     } else {
964                         dprintf(fd, "%" PRId32 " ",
965                                 *(int32_t*)(data_ptr + index));
966                     }
967                     break;
968                 case TYPE_FLOAT:
969                     dprintf(fd, "%0.8f ",
970                             *(float*)(data_ptr + index));
971                     break;
972                 case TYPE_INT64:
973                     dprintf(fd, "%" PRId64 " ",
974                             *(int64_t*)(data_ptr + index));
975                     break;
976                 case TYPE_DOUBLE:
977                     dprintf(fd, "%0.8f ",
978                             *(double*)(data_ptr + index));
979                     break;
980                 case TYPE_RATIONAL: {
981                     int32_t numerator = *(int32_t*)(data_ptr + index);
982                     int32_t denominator = *(int32_t*)(data_ptr + index + 4);
983                     dprintf(fd, "(%d / %d) ",
984                             numerator, denominator);
985                     break;
986                 }
987                 default:
988                     dprintf(fd, "??? ");
989             }
990         }
991         dprintf(fd, "]\n");
992     }
993 }
994