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