1 /*
2  * Copyright (C) 2013 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 //#define LOG_NDEBUG 0
17 #define LOG_TAG "VendorTags"
18 
19 #include <stdint.h>
20 
21 #include <log/log.h>
22 
23 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
24 #include <utils/Trace.h>
25 
26 #include <system/camera_metadata.h>
27 #include "Metadata.h"
28 
29 #include "VendorTags.h"
30 
31 namespace default_camera_hal {
32 
33 // Internal representations of vendor tags for convenience.
34 // Other classes must access this data via public interfaces.
35 // Structured to be easy to extend and contain complexity.
36 namespace {
37 // Describes a single vendor tag entry
38 struct Entry {
39     const char* name;
40     uint8_t     type;
41 };
42 // Describes a vendor tag section
43 struct Section {
44     const char* name;
45     uint32_t start;
46     uint32_t end;
47     const Entry* tags;
48 };
49 
50 // Entry arrays for each section
51 const Entry DemoWizardry[demo_wizardry_end - demo_wizardry_start] = {
52     [demo_wizardry_dimension_size - demo_wizardry_start] =
53         {"dimensionSize",   TYPE_INT32},
54     [demo_wizardry_dimensions - demo_wizardry_start] =
55         {"dimensions",      TYPE_INT32},
56     [demo_wizardry_familiar - demo_wizardry_start] =
57         {"familiar",        TYPE_BYTE},
58     [demo_wizardry_fire - demo_wizardry_start] =
59         {"fire",            TYPE_RATIONAL}
60 };
61 
62 const Entry DemoSorcery[demo_sorcery_end - demo_sorcery_start] = {
63     [demo_sorcery_difficulty - demo_sorcery_start] =
64         {"difficulty",      TYPE_INT64},
65     [demo_sorcery_light - demo_sorcery_start] =
66         {"light",           TYPE_BYTE}
67 };
68 
69 const Entry DemoMagic[demo_magic_end - demo_magic_start] = {
70     [demo_magic_card_trick - demo_magic_start] =
71         {"cardTrick",       TYPE_DOUBLE},
72     [demo_magic_levitation - demo_magic_start] =
73         {"levitation",      TYPE_FLOAT}
74 };
75 
76 // Array of all sections
77 const Section DemoSections[DEMO_SECTION_COUNT] = {
78     [DEMO_WIZARDRY] = { "demo.wizardry",
79                         demo_wizardry_start,
80                         demo_wizardry_end,
81                         DemoWizardry },
82     [DEMO_SORCERY]  = { "demo.sorcery",
83                         demo_sorcery_start,
84                         demo_sorcery_end,
85                         DemoSorcery },
86     [DEMO_MAGIC]    = { "demo.magic",
87                         demo_magic_start,
88                         demo_magic_end,
89                         DemoMagic }
90 };
91 
92 // Get a static handle to a specific vendor tag section
getSection(uint32_t tag)93 const Section* getSection(uint32_t tag)
94 {
95     uint32_t section = (tag - vendor_section_start) >> 16;
96 
97     if (tag < vendor_section_start) {
98         ALOGE("%s: Tag 0x%x before vendor section", __func__, tag);
99         return NULL;
100     }
101 
102     if (section >= DEMO_SECTION_COUNT) {
103         ALOGE("%s: Tag 0x%x after vendor section", __func__, tag);
104         return NULL;
105     }
106 
107     return &DemoSections[section];
108 }
109 
110 // Get a static handle to a specific vendor tag entry
getEntry(uint32_t tag)111 const Entry* getEntry(uint32_t tag)
112 {
113     const Section* section = getSection(tag);
114     int index;
115 
116     if (section == NULL)
117         return NULL;
118 
119     if (tag >= section->end) {
120         ALOGE("%s: Tag 0x%x outside section", __func__, tag);
121         return NULL;
122     }
123 
124     index = tag - section->start;
125     return &section->tags[index];
126 }
127 } // namespace
128 
VendorTags()129 VendorTags::VendorTags()
130   : mTagCount(0)
131 {
132     for (int i = 0; i < DEMO_SECTION_COUNT; i++) {
133         mTagCount += DemoSections[i].end - DemoSections[i].start;
134     }
135 }
136 
~VendorTags()137 VendorTags::~VendorTags()
138 {
139 }
140 
getTagCount(const vendor_tag_ops_t *)141 int VendorTags::getTagCount(const vendor_tag_ops_t* /*ops*/)
142 {
143     return mTagCount;
144 }
145 
getAllTags(const vendor_tag_ops_t *,uint32_t * tag_array)146 void VendorTags::getAllTags(const vendor_tag_ops_t* /*ops*/,
147         uint32_t* tag_array)
148 {
149     if (tag_array == NULL) {
150         ALOGE("%s: NULL tag_array", __func__);
151         return;
152     }
153 
154     for (int i = 0; i < DEMO_SECTION_COUNT; i++) {
155         for (uint32_t tag = DemoSections[i].start;
156                 tag < DemoSections[i].end; tag++) {
157             *tag_array++ = tag;
158         }
159     }
160 }
161 
getSectionName(const vendor_tag_ops_t *,uint32_t tag)162 const char* VendorTags::getSectionName(const vendor_tag_ops_t* /*ops*/,
163         uint32_t tag)
164 {
165     const Section* section = getSection(tag);
166 
167     if (section == NULL)
168         return NULL;
169 
170     return section->name;
171 }
172 
getTagName(const vendor_tag_ops_t *,uint32_t tag)173 const char* VendorTags::getTagName(const vendor_tag_ops_t* /*ops*/,
174         uint32_t tag)
175 {
176     const Entry* entry = getEntry(tag);
177 
178     if (entry == NULL)
179         return NULL;
180 
181     return entry->name;
182 }
183 
getTagType(const vendor_tag_ops_t *,uint32_t tag)184 int VendorTags::getTagType(const vendor_tag_ops_t* /*ops*/, uint32_t tag)
185 {
186     const Entry* entry = getEntry(tag);
187 
188     if (entry == NULL)
189         return -1;
190 
191     return entry->type;
192 }
193 } // namespace default_camera_hal
194