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 #include <system/camera_metadata.h>
18 #include <camera_metadata_hidden.h>
19 
20 #define LOG_TAG "GCH_VendorTagUtils"
21 #include <log/log.h>
22 
23 #include <map>
24 #include <string>
25 #include <unordered_set>
26 
27 #include "vendor_tag_utils.h"
28 
29 namespace android {
30 namespace google_camera_hal {
31 namespace vendor_tag_utils {
32 
CombineVendorTags(const std::vector<VendorTagSection> & source1,const std::vector<VendorTagSection> & source2,std::vector<VendorTagSection> * destination)33 status_t CombineVendorTags(const std::vector<VendorTagSection>& source1,
34                            const std::vector<VendorTagSection>& source2,
35                            std::vector<VendorTagSection>* destination) {
36   if (destination == nullptr) {
37     ALOGE("%s destination is nullptr", __FUNCTION__);
38     return BAD_VALUE;
39   }
40 
41   // Temporary sets to guarantee the uniqueness of IDs and tag names
42   std::unordered_set<std::string> tag_names;
43   std::unordered_set<uint32_t> tag_ids;
44   // Maps unique vendor tag section names to a list of tags
45   std::map<std::string, std::vector<VendorTag>> section_tags;
46 
47   // Loop through the source1 and source2 section lists
48   for (auto& section_list : {source1, source2}) {
49     // Loop through every section
50     for (const VendorTagSection& section : section_list) {
51       // Loop through every tag in this section's tag list
52       for (const VendorTag& tag : section.tags) {
53         section_tags[section.section_name].push_back(tag);
54 
55         // Ensure that the vendor tag name is unique
56         std::string full_tag_name = section.section_name + "." + tag.tag_name;
57         auto [name_it, name_inserted] = tag_names.insert(full_tag_name);
58         if (!name_inserted) {
59           ALOGE(
60               "%s Error! Vendor tag name collision: Tag %s is used more than "
61               "once",
62               __FUNCTION__, full_tag_name.c_str());
63           return BAD_VALUE;
64         }
65 
66         // Ensure that the vendor tag ID is unique
67         auto [id_it, id_inserted] = tag_ids.insert(tag.tag_id);
68         if (!id_inserted) {
69           ALOGE(
70               "%s Error! Vendor tag ID collision: Tag 0x%x (%u) is used more "
71               "than once",
72               __FUNCTION__, tag.tag_id, tag.tag_id);
73           return BAD_VALUE;
74         }
75       }
76     }
77   }
78 
79   // Convert the section_tags map to the resulting type
80   destination->resize(section_tags.size());
81   size_t index = 0;
82   for (auto& [section_name, section_tags] : section_tags) {
83     destination->at(index).section_name = section_name;
84     destination->at(index).tags = section_tags;
85     index++;
86   }
87 
88   return OK;
89 }
90 }  // namespace vendor_tag_utils
91 
92 // Vendor tag operations called by the camera metadata framework
GetCount(const vendor_tag_ops_t *)93 static int GetCount(const vendor_tag_ops_t* /*tag_ops*/) {
94   return VendorTagManager::GetInstance().GetCount();
95 }
96 
GetAllTags(const vendor_tag_ops_t *,uint32_t * tag_array)97 static void GetAllTags(const vendor_tag_ops_t* /*tag_ops*/,
98                        uint32_t* tag_array) {
99   return VendorTagManager::GetInstance().GetAllTags(tag_array);
100 }
101 
GetSectionName(const vendor_tag_ops_t *,uint32_t tag_id)102 static const char* GetSectionName(const vendor_tag_ops_t* /*tag_ops*/,
103                                   uint32_t tag_id) {
104   return VendorTagManager::GetInstance().GetSectionName(tag_id);
105 }
106 
GetTagName(const vendor_tag_ops_t *,uint32_t tag_id)107 static const char* GetTagName(const vendor_tag_ops_t* /*tag_ops*/,
108                               uint32_t tag_id) {
109   return VendorTagManager::GetInstance().GetTagName(tag_id);
110 }
111 
GetTagType(const vendor_tag_ops_t *,uint32_t tag_id)112 static int GetTagType(const vendor_tag_ops_t* /*tag_ops*/, uint32_t tag_id) {
113   return VendorTagManager::GetInstance().GetTagType(tag_id);
114 }
115 
GetInstance()116 VendorTagManager& VendorTagManager::GetInstance() {
117   static VendorTagManager instance;
118   return instance;
119 }
120 
AddTags(const std::vector<VendorTagSection> & tag_sections)121 status_t VendorTagManager::AddTags(
122     const std::vector<VendorTagSection>& tag_sections) {
123   std::lock_guard<std::mutex> lock(api_mutex_);
124 
125   std::vector<VendorTagSection> combined_tags;
126   status_t res = vendor_tag_utils::CombineVendorTags(
127       tag_sections_, tag_sections, &combined_tags);
128   if (res != OK) {
129     ALOGE("%s: CombineVendorTags() failed: %s(%d)", __FUNCTION__,
130           strerror(-res), res);
131     return res;
132   }
133   tag_sections_ = combined_tags;
134 
135   // Add new tags to internal maps to help speed up the metadata framework
136   // lookup calls
137   for (auto& section : tag_sections) {
138     for (auto& tag : section.tags) {
139       vendor_tag_map_[tag.tag_id] =
140           VendorTagInfo{.tag_id = tag.tag_id,
141                         .tag_type = static_cast<int>(tag.tag_type),
142                         .section_name = section.section_name,
143                         .tag_name = tag.tag_name};
144 
145       vendor_tag_inverse_map_[TagString(section.section_name, tag.tag_name)] =
146           tag.tag_id;
147     }
148   }
149 
150   // Vendor tag callbacks used by the camera metadata framework
151   static vendor_tag_ops_t vendor_tag_ops = {
152       .get_tag_count = google_camera_hal::GetCount,
153       .get_all_tags = google_camera_hal::GetAllTags,
154       .get_section_name = google_camera_hal::GetSectionName,
155       .get_tag_name = google_camera_hal::GetTagName,
156       .get_tag_type = google_camera_hal::GetTagType,
157   };
158   res = set_camera_metadata_vendor_ops(&vendor_tag_ops);
159   if (res != OK) {
160     ALOGE("%s: set_camera_metadata_vendor_ops() failed: %s(%d)", __FUNCTION__,
161           strerror(-res), res);
162     return res;
163   }
164 
165   return OK;
166 }
167 
GetTags() const168 const std::vector<VendorTagSection>& VendorTagManager::GetTags() const {
169   return tag_sections_;
170 }
171 
Reset()172 void VendorTagManager::Reset() {
173   std::lock_guard<std::mutex> lock(api_mutex_);
174   vendor_tag_map_.clear();
175   tag_sections_.clear();
176   set_camera_metadata_vendor_ops(nullptr);
177 }
178 
GetCount() const179 int VendorTagManager::GetCount() const {
180   std::lock_guard<std::mutex> lock(api_mutex_);
181   return static_cast<int>(vendor_tag_map_.size());
182 }
183 
GetAllTags(uint32_t * tag_array) const184 void VendorTagManager::GetAllTags(uint32_t* tag_array) const {
185   std::lock_guard<std::mutex> lock(api_mutex_);
186   if (tag_array == nullptr) {
187     ALOGE("%s tag_array is nullptr", __FUNCTION__);
188     return;
189   }
190 
191   uint32_t index = 0;
192   for (auto& [tag_id, tag_descriptor] : vendor_tag_map_) {
193     tag_array[index++] = tag_id;
194   }
195 }
196 
GetSectionName(uint32_t tag_id) const197 const char* VendorTagManager::GetSectionName(uint32_t tag_id) const {
198   std::lock_guard<std::mutex> lock(api_mutex_);
199   auto it = vendor_tag_map_.find(tag_id);
200   if (it == vendor_tag_map_.end()) {
201     ALOGE("%s Unknown vendor tag ID: %u", __FUNCTION__, tag_id);
202     return "unknown";
203   }
204 
205   return it->second.section_name.c_str();
206 }
207 
GetTagName(uint32_t tag_id) const208 const char* VendorTagManager::GetTagName(uint32_t tag_id) const {
209   std::lock_guard<std::mutex> lock(api_mutex_);
210   auto it = vendor_tag_map_.find(tag_id);
211   if (it == vendor_tag_map_.end()) {
212     ALOGE("%s Unknown vendor tag ID: %u", __FUNCTION__, tag_id);
213     return "unknown";
214   }
215 
216   return it->second.tag_name.c_str();
217 }
218 
GetTagType(uint32_t tag_id) const219 int VendorTagManager::GetTagType(uint32_t tag_id) const {
220   std::lock_guard<std::mutex> lock(api_mutex_);
221   auto it = vendor_tag_map_.find(tag_id);
222   if (it == vendor_tag_map_.end()) {
223     ALOGE("%s Unknown vendor tag ID: 0x%x (%u)", __FUNCTION__, tag_id, tag_id);
224     return -1;
225   }
226 
227   return it->second.tag_type;
228 }
229 
GetTagInfo(uint32_t tag_id,VendorTagInfo * tag_info)230 status_t VendorTagManager::GetTagInfo(uint32_t tag_id, VendorTagInfo* tag_info) {
231   if (tag_info == nullptr) {
232     ALOGE("%s tag_info is nullptr", __FUNCTION__);
233     return BAD_VALUE;
234   }
235   std::lock_guard<std::mutex> lock(api_mutex_);
236   auto itr = vendor_tag_map_.find(tag_id);
237   if (itr == vendor_tag_map_.end()) {
238     ALOGE("%s Given tag_id not found", __FUNCTION__);
239     return BAD_VALUE;
240   }
241 
242   *tag_info = itr->second;
243   return OK;
244 }
245 
GetTag(const std::string section_name,const std::string tag_name,uint32_t * tag_id)246 status_t VendorTagManager::GetTag(const std::string section_name,
247                                   const std::string tag_name, uint32_t* tag_id) {
248   if (tag_id == nullptr) {
249     ALOGE("%s tag_id is nullptr", __FUNCTION__);
250     return BAD_VALUE;
251   }
252   std::lock_guard<std::mutex> lock(api_mutex_);
253 
254   const TagString section_tag{section_name, tag_name};
255 
256   auto itr = vendor_tag_inverse_map_.find(section_tag);
257   if (itr == vendor_tag_inverse_map_.end()) {
258     ALOGE("%s Given section/tag names not found", __FUNCTION__);
259     return BAD_VALUE;
260   }
261 
262   *tag_id = itr->second;
263   return OK;
264 }
265 
266 }  // namespace google_camera_hal
267 }  // namespace android
268