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