1 /*
2 * Copyright (C) 2016 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 "partial_metadata_factory.h"
18
19 #include <camera/CameraMetadata.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 #include "converter_interface_mock.h"
24 #include "metadata_common.h"
25 #include "test_common.h"
26 #include "v4l2_wrapper_mock.h"
27
28 using testing::AtMost;
29 using testing::Expectation;
30 using testing::Return;
31 using testing::SetArgPointee;
32 using testing::Test;
33 using testing::_;
34
35 namespace v4l2_camera_hal {
36
37 class PartialMetadataFactoryTest : public Test {
38 protected:
SetUp()39 virtual void SetUp() {
40 mock_device_.reset(new V4L2WrapperMock());
41 mock_converter_.reset(new ConverterInterfaceMock<uint8_t, int32_t>());
42 // Nullify control so an error will be thrown
43 // if a test doesn't construct it.
44 control_.reset();
45 }
46
ExpectControlTags()47 virtual void ExpectControlTags() {
48 ASSERT_EQ(control_->StaticTags().size(), 1u);
49 EXPECT_EQ(control_->StaticTags()[0], options_tag_);
50 ASSERT_EQ(control_->ControlTags().size(), 1u);
51 EXPECT_EQ(control_->ControlTags()[0], delegate_tag_);
52 ASSERT_EQ(control_->DynamicTags().size(), 1u);
53 EXPECT_EQ(control_->DynamicTags()[0], delegate_tag_);
54 }
55
ExpectControlOptions(const std::vector<uint8_t> & options)56 virtual void ExpectControlOptions(const std::vector<uint8_t>& options) {
57 // Options should be available.
58 android::CameraMetadata metadata;
59 ASSERT_EQ(control_->PopulateStaticFields(&metadata), 0);
60 EXPECT_EQ(metadata.entryCount(), 1u);
61 ExpectMetadataEq(metadata, options_tag_, options);
62 }
63
ExpectControlValue(uint8_t value)64 virtual void ExpectControlValue(uint8_t value) {
65 android::CameraMetadata metadata;
66 ASSERT_EQ(control_->PopulateDynamicFields(&metadata), 0);
67 EXPECT_EQ(metadata.entryCount(), 1u);
68 ExpectMetadataEq(metadata, delegate_tag_, value);
69 }
70
71 std::unique_ptr<Control<uint8_t>> control_;
72 std::shared_ptr<ConverterInterfaceMock<uint8_t, int32_t>> mock_converter_;
73 std::shared_ptr<V4L2WrapperMock> mock_device_;
74
75 // Need tags that match the data type (uint8_t) being passed.
76 const int32_t delegate_tag_ = ANDROID_COLOR_CORRECTION_ABERRATION_MODE;
77 const int32_t options_tag_ =
78 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
79 };
80
81 class DISABLED_PartialMetadataFactoryTest : public PartialMetadataFactoryTest {
82 };
83
TEST_F(PartialMetadataFactoryTest,FixedState)84 TEST_F(PartialMetadataFactoryTest, FixedState) {
85 uint8_t value = 13;
86 std::unique_ptr<State<uint8_t>> state = FixedState(delegate_tag_, value);
87
88 ASSERT_EQ(state->StaticTags().size(), 0u);
89 ASSERT_EQ(state->ControlTags().size(), 0u);
90 ASSERT_EQ(state->DynamicTags().size(), 1u);
91 EXPECT_EQ(state->DynamicTags()[0], delegate_tag_);
92
93 android::CameraMetadata metadata;
94 ASSERT_EQ(state->PopulateDynamicFields(&metadata), 0);
95 EXPECT_EQ(metadata.entryCount(), 1u);
96 ExpectMetadataEq(metadata, delegate_tag_, value);
97 }
98
TEST_F(PartialMetadataFactoryTest,NoEffectMenu)99 TEST_F(PartialMetadataFactoryTest, NoEffectMenu) {
100 std::vector<uint8_t> test_options = {9, 8, 12};
101 control_ =
102 NoEffectMenuControl<uint8_t>(delegate_tag_, options_tag_, test_options);
103 ASSERT_NE(control_, nullptr);
104
105 ExpectControlTags();
106
107 // Options should be available.
108 ExpectControlOptions(test_options);
109 // Default value should be test_options[0].
110 ExpectControlValue(test_options[0]);
111 }
112
TEST_F(PartialMetadataFactoryTest,NoEffectGenericMenu)113 TEST_F(PartialMetadataFactoryTest, NoEffectGenericMenu) {
114 uint8_t default_val = 9;
115 control_ = NoEffectControl<uint8_t>(
116 ControlType::kMenu, delegate_tag_, options_tag_, default_val);
117 ASSERT_NE(control_, nullptr);
118
119 ExpectControlTags();
120
121 // Options should be available.
122 ExpectControlOptions({default_val});
123 // |default_val| should be default option.
124 ExpectControlValue(default_val);
125 }
126
TEST_F(PartialMetadataFactoryTest,NoEffectSlider)127 TEST_F(PartialMetadataFactoryTest, NoEffectSlider) {
128 std::vector<uint8_t> test_range = {9, 12};
129 control_ = NoEffectSliderControl<uint8_t>(
130 delegate_tag_, options_tag_, test_range[0], test_range[1]);
131 ASSERT_NE(control_, nullptr);
132
133 ExpectControlTags();
134
135 // Single option should be available.
136 ExpectControlOptions(test_range);
137 // Default value should be the minimum (test_range[0]).
138 ExpectControlValue(test_range[0]);
139 }
140
TEST_F(PartialMetadataFactoryTest,NoEffectGenericSlider)141 TEST_F(PartialMetadataFactoryTest, NoEffectGenericSlider) {
142 uint8_t default_val = 9;
143 control_ = NoEffectControl<uint8_t>(
144 ControlType::kSlider, delegate_tag_, options_tag_, default_val);
145 ASSERT_NE(control_, nullptr);
146
147 ExpectControlTags();
148
149 // Range containing only |default_val| should be available.
150 ExpectControlOptions({default_val, default_val});
151 // |default_val| should be default option.
152 ExpectControlValue(default_val);
153 }
154
TEST_F(PartialMetadataFactoryTest,V4L2FactoryQueryFail)155 TEST_F(PartialMetadataFactoryTest, V4L2FactoryQueryFail) {
156 int control_id = 55;
157 // Should query the device.
158 EXPECT_CALL(*mock_device_, QueryControl(control_id, _)).WillOnce(Return(-1));
159 control_ = V4L2Control<uint8_t>(ControlType::kMenu,
160 delegate_tag_,
161 options_tag_,
162 mock_device_,
163 control_id,
164 mock_converter_);
165 // Failure, should return null.
166 ASSERT_EQ(control_, nullptr);
167 }
168
TEST_F(PartialMetadataFactoryTest,V4L2FactoryQueryBadType)169 TEST_F(PartialMetadataFactoryTest, V4L2FactoryQueryBadType) {
170 int control_id = 55;
171 v4l2_query_ext_ctrl query_result;
172 query_result.type = V4L2_CTRL_TYPE_CTRL_CLASS;
173 // Should query the device.
174 EXPECT_CALL(*mock_device_, QueryControl(control_id, _))
175 .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
176 control_ = V4L2Control<uint8_t>(ControlType::kMenu,
177 delegate_tag_,
178 options_tag_,
179 mock_device_,
180 control_id,
181 mock_converter_);
182 // Failure, should return null.
183 ASSERT_EQ(control_, nullptr);
184 }
185
TEST_F(PartialMetadataFactoryTest,V4L2FactoryQueryBadRange)186 TEST_F(PartialMetadataFactoryTest, V4L2FactoryQueryBadRange) {
187 int control_id = 55;
188 v4l2_query_ext_ctrl query_result;
189 query_result.type = V4L2_CTRL_TYPE_MENU;
190 query_result.minimum = 10;
191 query_result.maximum = 1; // Less than minimum.
192 // Should query the device.
193 EXPECT_CALL(*mock_device_, QueryControl(control_id, _))
194 .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
195 control_ = V4L2Control<uint8_t>(ControlType::kMenu,
196 delegate_tag_,
197 options_tag_,
198 mock_device_,
199 control_id,
200 mock_converter_);
201 // Failure, should return null.
202 ASSERT_EQ(control_, nullptr);
203 }
204
TEST_F(PartialMetadataFactoryTest,V4L2FactoryTypeRequestMenuMismatch)205 TEST_F(PartialMetadataFactoryTest, V4L2FactoryTypeRequestMenuMismatch) {
206 int control_id = 55;
207 v4l2_query_ext_ctrl query_result;
208 query_result.type = V4L2_CTRL_TYPE_INTEGER;
209 query_result.minimum = 1;
210 query_result.maximum = 7;
211 query_result.step = 2;
212 // Have conversions for values 1-5, by step size 2.
213 std::map<int32_t, uint8_t> conversion_map = {{1, 10}, {3, 30}, {5, 50}};
214
215 // Should query the device.
216 EXPECT_CALL(*mock_device_, QueryControl(control_id, _))
217 .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
218
219 // If you ask for a Menu, but the V4L2 control is a slider type, that's bad.
220 control_ = V4L2Control<uint8_t>(ControlType::kMenu,
221 delegate_tag_,
222 options_tag_,
223 mock_device_,
224 control_id,
225 mock_converter_);
226 ASSERT_EQ(control_, nullptr);
227 }
228
TEST_F(PartialMetadataFactoryTest,V4L2FactoryTypeRequestSliderMismatch)229 TEST_F(PartialMetadataFactoryTest, V4L2FactoryTypeRequestSliderMismatch) {
230 int control_id = 55;
231 v4l2_query_ext_ctrl query_result;
232 query_result.type = V4L2_CTRL_TYPE_MENU;
233 query_result.minimum = 1;
234 query_result.maximum = 7;
235 query_result.step = 2;
236 // Have conversions for values 1-5, by step size 2.
237 std::map<int32_t, uint8_t> conversion_map = {{1, 10}, {3, 30}, {5, 50}};
238
239 // Should query the device.
240 EXPECT_CALL(*mock_device_, QueryControl(control_id, _))
241 .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
242
243 // If you ask for a Slider and get a Menu, that's bad.
244 control_ = V4L2Control<uint8_t>(ControlType::kSlider,
245 delegate_tag_,
246 options_tag_,
247 mock_device_,
248 control_id,
249 mock_converter_);
250 ASSERT_EQ(control_, nullptr);
251 }
252
TEST_F(DISABLED_PartialMetadataFactoryTest,V4L2FactoryMenu)253 TEST_F(DISABLED_PartialMetadataFactoryTest, V4L2FactoryMenu) {
254 // TODO(b/30921166): Correct Menu support so this can be re-enabled.
255 int control_id = 55;
256 v4l2_query_ext_ctrl query_result;
257 query_result.type = V4L2_CTRL_TYPE_MENU;
258 query_result.minimum = 1;
259 query_result.maximum = 7;
260 query_result.step = 2;
261 // Have conversions for values 1-5, by step size 2.
262 std::map<int32_t, uint8_t> conversion_map = {{1, 10}, {3, 30}, {5, 50}};
263
264 // Should query the device.
265 EXPECT_CALL(*mock_device_, QueryControl(control_id, _))
266 .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
267 // Should convert values.
268 std::vector<uint8_t> expected_options;
269 for (auto kv : conversion_map) {
270 EXPECT_CALL(*mock_converter_, V4L2ToMetadata(kv.first, _))
271 .WillOnce(DoAll(SetArgPointee<1>(kv.second), Return(0)));
272 expected_options.push_back(kv.second);
273 }
274 // Will fail to convert 7 with -EINVAL, shouldn't matter.
275 EXPECT_CALL(*mock_converter_, V4L2ToMetadata(7, _)).WillOnce(Return(-EINVAL));
276
277 control_ = V4L2Control<uint8_t>(ControlType::kMenu,
278 delegate_tag_,
279 options_tag_,
280 mock_device_,
281 control_id,
282 mock_converter_);
283 ASSERT_NE(control_, nullptr);
284
285 ExpectControlTags();
286 ExpectControlOptions(expected_options);
287 }
288
TEST_F(DISABLED_PartialMetadataFactoryTest,V4L2FactoryMenuConversionFail)289 TEST_F(DISABLED_PartialMetadataFactoryTest, V4L2FactoryMenuConversionFail) {
290 // TODO(b/30921166): Correct Menu support so this can be re-enabled.
291 int control_id = 55;
292 v4l2_query_ext_ctrl query_result;
293 query_result.type = V4L2_CTRL_TYPE_MENU;
294 query_result.minimum = 1;
295 query_result.maximum = 7;
296 query_result.step = 2;
297
298 // Should query the device.
299 EXPECT_CALL(*mock_device_, QueryControl(control_id, _))
300 .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
301 // Conversion fails with non-EINVAL error.
302 EXPECT_CALL(*mock_converter_, V4L2ToMetadata(_, _)).WillOnce(Return(-1));
303
304 control_ = V4L2Control<uint8_t>(ControlType::kMenu,
305 delegate_tag_,
306 options_tag_,
307 mock_device_,
308 control_id,
309 mock_converter_);
310 ASSERT_EQ(control_, nullptr);
311 }
312
TEST_F(DISABLED_PartialMetadataFactoryTest,V4L2FactoryMenuNoConversions)313 TEST_F(DISABLED_PartialMetadataFactoryTest, V4L2FactoryMenuNoConversions) {
314 // TODO(b/30921166): Correct Menu support so this can be re-enabled.
315 int control_id = 55;
316 v4l2_query_ext_ctrl query_result;
317 query_result.type = V4L2_CTRL_TYPE_MENU;
318 query_result.minimum = 1;
319 query_result.maximum = 1;
320 query_result.step = 1;
321
322 // Should query the device.
323 EXPECT_CALL(*mock_device_, QueryControl(control_id, _))
324 .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
325 // Conversion fails with -EINVAL error.
326 EXPECT_CALL(*mock_converter_, V4L2ToMetadata(1, _)).WillOnce(Return(-EINVAL));
327
328 control_ = V4L2Control<uint8_t>(ControlType::kMenu,
329 delegate_tag_,
330 options_tag_,
331 mock_device_,
332 control_id,
333 mock_converter_);
334 // Since there were no convertable options, should fail.
335 ASSERT_EQ(control_, nullptr);
336 }
337
TEST_F(PartialMetadataFactoryTest,V4L2FactoryInteger)338 TEST_F(PartialMetadataFactoryTest, V4L2FactoryInteger) {
339 int control_id = 55;
340 v4l2_query_ext_ctrl query_result;
341 query_result.type = V4L2_CTRL_TYPE_INTEGER;
342 query_result.minimum = 1;
343 query_result.maximum = 7;
344 query_result.step = 2;
345 // Have conversions for values 1 & 7.
346 std::map<int32_t, uint8_t> conversion_map = {{1, 10}, {7, 70}};
347
348 // Should query the device.
349 EXPECT_CALL(*mock_device_, QueryControl(control_id, _))
350 .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
351 // Should convert values.
352 std::vector<uint8_t> expected_options;
353 for (auto kv : conversion_map) {
354 EXPECT_CALL(*mock_converter_, V4L2ToMetadata(kv.first, _))
355 .WillOnce(DoAll(SetArgPointee<1>(kv.second), Return(0)));
356 expected_options.push_back(kv.second);
357 }
358
359 control_ = V4L2Control<uint8_t>(ControlType::kSlider,
360 delegate_tag_,
361 options_tag_,
362 mock_device_,
363 control_id,
364 mock_converter_);
365 ASSERT_NE(control_, nullptr);
366
367 ExpectControlTags();
368 ExpectControlOptions(expected_options);
369
370 // Should be fitting converted values to steps.
371 uint8_t set_val = 10;
372 android::CameraMetadata metadata;
373 EXPECT_EQ(UpdateMetadata(&metadata, delegate_tag_, set_val), 0);
374 EXPECT_CALL(*mock_converter_, MetadataToV4L2(set_val, _))
375 .WillOnce(DoAll(SetArgPointee<1>(4), Return(0)));
376 // When it calls into the device, the 4 returned above should be
377 // rounded down to the step value of 3.
378 EXPECT_CALL(*mock_device_, SetControl(control_id, 3, _)).WillOnce(Return(0));
379 EXPECT_EQ(control_->SetRequestValues(metadata), 0);
380 }
381
TEST_F(PartialMetadataFactoryTest,V4L2FactoryIntegerFailedConversion)382 TEST_F(PartialMetadataFactoryTest, V4L2FactoryIntegerFailedConversion) {
383 int control_id = 55;
384 v4l2_query_ext_ctrl query_result;
385 query_result.type = V4L2_CTRL_TYPE_INTEGER;
386 query_result.minimum = 1;
387 query_result.maximum = 7;
388 query_result.step = 2;
389
390 // Should query the device.
391 EXPECT_CALL(*mock_device_, QueryControl(control_id, _))
392 .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
393 // Fail to convert a value. Even -EINVAL is bad in this case.
394 EXPECT_CALL(*mock_converter_, V4L2ToMetadata(1, _)).WillOnce(Return(-EINVAL));
395
396 control_ = V4L2Control<uint8_t>(ControlType::kSlider,
397 delegate_tag_,
398 options_tag_,
399 mock_device_,
400 control_id,
401 mock_converter_);
402 ASSERT_EQ(control_, nullptr);
403 }
404
TEST_F(PartialMetadataFactoryTest,V4L2FallbackMenu)405 TEST_F(PartialMetadataFactoryTest, V4L2FallbackMenu) {
406 uint8_t default_val = 9;
407 int control_id = 55;
408
409 // Should query the device.
410 EXPECT_CALL(*mock_device_, QueryControl(control_id, _)).WillOnce(Return(-1));
411
412 // Shouldn't fail, should fall back to menu control.
413 control_ = V4L2ControlOrDefault<uint8_t>(ControlType::kMenu,
414 delegate_tag_,
415 options_tag_,
416 mock_device_,
417 control_id,
418 mock_converter_,
419 default_val);
420 ASSERT_NE(control_, nullptr);
421
422 ExpectControlTags();
423
424 // Options should be available.
425 ExpectControlOptions({default_val});
426 // |default_val| should be default option.
427 ExpectControlValue(default_val);
428 }
429
TEST_F(PartialMetadataFactoryTest,V4L2FallbackSlider)430 TEST_F(PartialMetadataFactoryTest, V4L2FallbackSlider) {
431 uint8_t default_val = 9;
432 int control_id = 55;
433
434 // Should query the device.
435 EXPECT_CALL(*mock_device_, QueryControl(control_id, _)).WillOnce(Return(-1));
436
437 // Shouldn't fail, should fall back to slider control.
438 control_ = V4L2ControlOrDefault<uint8_t>(ControlType::kSlider,
439 delegate_tag_,
440 options_tag_,
441 mock_device_,
442 control_id,
443 mock_converter_,
444 default_val);
445 ASSERT_NE(control_, nullptr);
446
447 ExpectControlTags();
448
449 // Range containing only |default_val| should be available.
450 ExpectControlOptions({default_val, default_val});
451 // |default_val| should be default option.
452 ExpectControlValue(default_val);
453 }
454
455 } // namespace v4l2_camera_hal
456