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 <gtest/gtest.h>
18 #define LOG_TAG "CameraVendorTagTests"
19 #include <log/log.h>
20 
21 #include <vector>
22 
23 #include "system/camera_metadata.h"
24 #include "vendor_tag_defs.h"
25 #include "vendor_tag_utils.h"
26 #include "vendor_tags.h"
27 
28 namespace android {
29 namespace google_camera_hal {
30 
31 static constexpr uint32_t kDataBytes = 256;
32 static constexpr uint32_t kNumEntries = 10;
33 
TEST(CameraVendorTagTest,TestCharacteristics)34 TEST(CameraVendorTagTest, TestCharacteristics) {
35   auto hal_metadata = HalCameraMetadata::Create(kNumEntries, kDataBytes);
36   ASSERT_NE(hal_metadata, nullptr) << "Creating hal_metadata failed.";
37 
38   std::vector<uint32_t> dummy_keys = {
39       VendorTagIds::kLogicalCamDefaultPhysicalId};
40   status_t res = hal_metadata->Set(
41       ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
42       reinterpret_cast<int32_t*>(dummy_keys.data()), dummy_keys.size());
43   ASSERT_EQ(res, OK);
44 
45   res = hal_metadata->Set(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
46                           reinterpret_cast<int32_t*>(dummy_keys.data()),
47                           dummy_keys.size());
48   ASSERT_EQ(res, OK);
49 
50   res = hal_metadata->Set(ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
51                           reinterpret_cast<int32_t*>(dummy_keys.data()),
52                           dummy_keys.size());
53   ASSERT_EQ(res, OK);
54 
55   res = hal_metadata->Set(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
56                           reinterpret_cast<int32_t*>(dummy_keys.data()),
57                           dummy_keys.size());
58   ASSERT_EQ(res, OK);
59 
60   res = hal_vendor_tag_utils::ModifyCharacteristicsKeys(hal_metadata.get());
61   EXPECT_EQ(res, OK);
62 
63   res = hal_vendor_tag_utils::ModifyCharacteristicsKeys(nullptr);
64   EXPECT_NE(res, OK) << "ModifyCameraCharacteristics() should have failed with "
65                         "a nullptr metadata";
66 }
67 
TEST(CameraVendorTagTest,TestDefaultRequest)68 TEST(CameraVendorTagTest, TestDefaultRequest) {
69   std::vector<RequestTemplate> request_templates = {
70       RequestTemplate::kPreview, RequestTemplate::kStillCapture,
71       RequestTemplate::kVideoRecord, RequestTemplate::kVideoSnapshot,
72       RequestTemplate::kZeroShutterLag};
73 
74   status_t res;
75   for (auto& request_template : request_templates) {
76     auto hal_metadata = HalCameraMetadata::Create(kNumEntries, kDataBytes);
77     ASSERT_NE(hal_metadata, nullptr) << "Creating hal_metadata failed.";
78 
79     res = hal_vendor_tag_utils::ModifyDefaultRequestSettings(
80         request_template, hal_metadata.get());
81     EXPECT_EQ(res, OK) << "ModifyDefaultRequestSettings() failed for request "
82                           "template (%u)"
83                        << static_cast<uint32_t>(request_template);
84   }
85 }
86 
TEST(CameraVendorTagTest,TestValidVendorTags)87 TEST(CameraVendorTagTest, TestValidVendorTags) {
88   uint32_t hwl_tag_id = VENDOR_SECTION_START;
89   uint32_t hal_tag_id = kHalVendorTagSectionStart;
90 
91   ASSERT_LT(hwl_tag_id, hal_tag_id) << "Error! HAL vendor tag section start "
92                                     << "must be greater than "
93                                     << "VENDOR_SECTION_START";
94 
95   std::vector<VendorTagSection> hwl_sections = {
96       {.section_name = "com.google.hwl.internal",
97        .tags = {{.tag_id = hwl_tag_id++,
98                  .tag_name = "magic",
99                  .tag_type = CameraMetadataType::kFloat},
100                 {.tag_id = hwl_tag_id++,
101                  .tag_name = "wand",
102                  .tag_type = CameraMetadataType::kFloat}}},
103       {.section_name = "com.google.3a",
104        .tags = {{.tag_id = hwl_tag_id++,
105                  .tag_name = "aec",
106                  .tag_type = CameraMetadataType::kFloat},
107                 {.tag_id = hwl_tag_id++,
108                  .tag_name = "awb",
109                  .tag_type = CameraMetadataType::kInt32}}}};
110 
111   std::vector<VendorTagSection> hal_sections = {
112       {.section_name = "com.pixel.experimental",
113        .tags = {{.tag_id = hal_tag_id++,
114                  .tag_name = "hybrid_ae.enabled",
115                  .tag_type = CameraMetadataType::kByte}}},
116       /* Overlaps with HWL vendor section above; this is allowed */
117       {.section_name = "com.google.3a",
118        .tags = {{.tag_id = hal_tag_id++,
119                  .tag_name = "af",
120                  .tag_type = CameraMetadataType::kFloat}}}};
121 
122   std::vector<VendorTagSection> combined_sections;
123   status_t ret = vendor_tag_utils::CombineVendorTags(hwl_sections, hal_sections,
124                                                      &combined_sections);
125 
126   EXPECT_EQ(ret, OK) << "CombineVendorTags() failed for valid tags!";
127 
128   ret = vendor_tag_utils::CombineVendorTags(hwl_sections, hal_sections,
129                                             /*destination=*/nullptr);
130   EXPECT_NE(ret, OK) << "CombineVendorTags() should have failed with nullptr";
131 
132   // Test metadata operations on above tags. They should fail since the camera
133   // framework hasn't been initialized via VendorTagManager utility class
134   auto metadata = HalCameraMetadata::Create(kNumEntries, kDataBytes);
135   ASSERT_NE(metadata, nullptr) << "Creating metadata failed.";
136   // Hard coded vendor tag ID for 'com.google.hwl.internal.magic' from above
137   uint32_t magic_tag_id = VENDOR_SECTION_START;
138   float good_magic = 42.1337f;
139   // Try to set a random value to above vendor tag
140   ret = metadata->Set(magic_tag_id, &good_magic, /*count=*/1);
141   EXPECT_NE(ret, OK) << "Error! Setting metadata should have failed before "
142                      << "initializing VendorTagManager";
143 
144   // Framework camera_metadata operations relying on 'vendor_tag_ops_t' should
145   // fail before VendorTagManager is initialized with the vendor tags
146   int count = VendorTagManager::GetInstance().GetCount();
147   EXPECT_EQ(0, count) << "Error! VendorTagManager should return a count of 0"
148                       << " before being initialized";
149 
150   // Now initialize VendorTagManager, and expect metadata operations same
151   // as previously done above to succeed
152   ret = VendorTagManager::GetInstance().AddTags(combined_sections);
153   ASSERT_EQ(ret, OK);
154   count = VendorTagManager::GetInstance().GetCount();
155   int expected_count = 0;
156   for (auto& section : hal_sections) {
157     expected_count += section.tags.size();
158   }
159   for (auto& section : hwl_sections) {
160     expected_count += section.tags.size();
161   }
162   EXPECT_EQ(count, expected_count);
163 
164   ret = metadata->Set(magic_tag_id, &good_magic, /*count=*/1);
165   EXPECT_EQ(ret, OK) << "Error! Setting metadata should have succeeded after "
166                      << "initializing VendorTagManager";
167 
168   // Try setting metadata with an invalid type (expected is float)
169   int32_t dark_magic = 13;
170   ret = metadata->Set(magic_tag_id, &dark_magic, /*count=*/1);
171   EXPECT_NE(ret, OK) << "Error! Setting metadata with an incorrect payload "
172                      << "type should have failed";
173 
174   // For debugging fun - print the combined list of vendor tags
175   ALOGI("Vendor tag list START");
176   ALOGI("---------------------");
177   if (count > 0) {
178     uint32_t* tag_id_list = new uint32_t[count];
179     VendorTagManager::GetInstance().GetAllTags(tag_id_list);
180     for (int i = 0; i < count; i++) {
181       uint32_t tag_id = tag_id_list[i];
182       const char* section_name =
183           VendorTagManager::GetInstance().GetSectionName(tag_id);
184       const char* tag_name = VendorTagManager::GetInstance().GetTagName(tag_id);
185       int tag_type = VendorTagManager::GetInstance().GetTagType(tag_id);
186       ALOGI("ID: 0x%x (%u)\tType: %d\t%s.%s", tag_id, tag_id, tag_type,
187             section_name, tag_name);
188     }
189 
190     delete[] tag_id_list;
191     ALOGI("Vendor tag list END");
192     ALOGI("-------------------");
193   }
194 
195   ret = VendorTagManager::GetInstance().AddTags(combined_sections);
196   EXPECT_NE(ret, OK) << "Calling AddTags with the same tags should fail.";
197 
198   std::vector<VendorTagSection> extra_sections = {
199       {.section_name = "extra_section",
200        .tags = {{.tag_id = hal_tag_id++,
201                  .tag_name = "extra_tag",
202                  .tag_type = CameraMetadataType::kByte}}}};
203 
204   ret = VendorTagManager::GetInstance().AddTags(extra_sections);
205   EXPECT_EQ(ret, OK) << "Adding extra tag sections should succeed";
206   expected_count += 1;
207   count = VendorTagManager::GetInstance().GetCount();
208   EXPECT_EQ(count, expected_count);
209 
210   VendorTagManager::GetInstance().Reset();
211   count = VendorTagManager::GetInstance().GetCount();
212   EXPECT_EQ(0, count) << "Error! VendorTagManager should return a count of 0"
213                       << " after being reset";
214 }
215 
TEST(CameraVendorTagTest,TestVendorTagsOverlappingIds)216 TEST(CameraVendorTagTest, TestVendorTagsOverlappingIds) {
217   // Make the HAL and HWL tag IDs overlap
218   uint32_t hwl_tag_id = kHalVendorTagSectionStart;
219   uint32_t hal_tag_id = kHalVendorTagSectionStart;
220 
221   std::vector<VendorTagSection> hwl_sections = {
222       {.section_name = "com.google.hwl.internal",
223        .tags = {{.tag_id = hwl_tag_id++,
224                  .tag_name = "magic",
225                  .tag_type = CameraMetadataType::kFloat},
226                 {.tag_id = hwl_tag_id++,
227                  .tag_name = "wand",
228                  .tag_type = CameraMetadataType::kFloat}}},
229       {.section_name = "com.google.hwl.3a",
230        .tags = {{.tag_id = hwl_tag_id++,
231                  .tag_name = "aec",
232                  .tag_type = CameraMetadataType::kFloat},
233                 {.tag_id = hwl_tag_id++,
234                  .tag_name = "awb",
235                  .tag_type = CameraMetadataType::kInt32}}}};
236 
237   std::vector<VendorTagSection> hal_sections = {
238       {.section_name = "com.pixel.experimental",
239        .tags = {{.tag_id = hal_tag_id++,
240                  .tag_name = "hybrid_ae.enabled",
241                  .tag_type = CameraMetadataType::kByte}}},
242       {.section_name = "com.google.hwl.3a",
243        .tags = {{.tag_id = hal_tag_id++,
244                  .tag_name = "af",
245                  .tag_type = CameraMetadataType::kFloat}}}};
246 
247   std::vector<VendorTagSection> combined_sections;
248   status_t ret = vendor_tag_utils::CombineVendorTags(hwl_sections, hal_sections,
249                                                      &combined_sections);
250 
251   EXPECT_NE(ret, OK) << "CombineVendorTags() succeeded for invalid tags!";
252 }
253 
TEST(CameraVendorTagTest,TestVendorTagsOverlappingNames)254 TEST(CameraVendorTagTest, TestVendorTagsOverlappingNames) {
255   uint32_t hwl_tag_id = VENDOR_SECTION_START;
256   uint32_t hal_tag_id = kHalVendorTagSectionStart;
257 
258   // Define duplicate tag name in both sections: com.google.hwl.3a.aec
259   std::vector<VendorTagSection> hwl_sections = {
260       {.section_name = "com.google.hwl.internal",
261        .tags = {{.tag_id = hwl_tag_id++,
262                  .tag_name = "magic",
263                  .tag_type = CameraMetadataType::kFloat},
264                 {.tag_id = hwl_tag_id++,
265                  .tag_name = "wand",
266                  .tag_type = CameraMetadataType::kFloat}}},
267       {.section_name = "com.google.hwl.3a",
268        .tags = {{.tag_id = hwl_tag_id++,
269                  .tag_name = "aec",
270                  .tag_type = CameraMetadataType::kFloat},
271                 {.tag_id = hwl_tag_id++,
272                  .tag_name = "awb",
273                  .tag_type = CameraMetadataType::kInt32}}}};
274 
275   std::vector<VendorTagSection> hal_sections = {
276       {.section_name = "com.pixel.experimental",
277        .tags = {{.tag_id = hal_tag_id++,
278                  .tag_name = "hybrid_ae.enabled",
279                  .tag_type = CameraMetadataType::kByte}}},
280       {.section_name = "com.google.hwl.3a",
281        .tags = {{.tag_id = hal_tag_id++,
282                  .tag_name = "aec",
283                  .tag_type = CameraMetadataType::kFloat}}}};
284 
285   std::vector<VendorTagSection> combined_sections;
286   status_t ret = vendor_tag_utils::CombineVendorTags(hwl_sections, hal_sections,
287                                                      &combined_sections);
288 
289   EXPECT_NE(ret, OK) << "CombineVendorTags() succeeded for invalid tags";
290 }
291 }  // namespace google_camera_hal
292 }  // namespace android
293