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 "metadata.h"
18 
19 #include <memory>
20 #include <set>
21 #include <vector>
22 
23 #include <camera/CameraMetadata.h>
24 #include <gmock/gmock.h>
25 #include <gtest/gtest.h>
26 
27 #include "metadata_common.h"
28 #include "partial_metadata_interface_mock.h"
29 
30 using testing::AtMost;
31 using testing::Return;
32 using testing::Test;
33 using testing::_;
34 
35 namespace v4l2_camera_hal {
36 
37 class MetadataTest : public Test {
38  protected:
SetUp()39   virtual void SetUp() {
40     // Clear the DUT. AddComponents must be called before using it.
41     dut_.reset();
42 
43     component1_.reset(new PartialMetadataInterfaceMock());
44     component2_.reset(new PartialMetadataInterfaceMock());
45     metadata_.reset(new android::CameraMetadata());
46     non_empty_metadata_.reset(new android::CameraMetadata());
47     uint8_t val = 1;
48     non_empty_metadata_->update(ANDROID_COLOR_CORRECTION_MODE, &val, 1);
49   }
50 
51   // Once the component mocks have had expectations set,
52   // add them to the device under test.
AddComponents()53   virtual void AddComponents() {
54     // Don't mind moving; Gmock/Gtest fails on leaked mocks unless disabled by
55     // runtime flags.
56     PartialMetadataSet components;
57     components.insert(std::move(component1_));
58     components.insert(std::move(component2_));
59     dut_.reset(new Metadata(std::move(components)));
60   }
61 
CompareTags(const std::set<int32_t> & expected,const camera_metadata_entry_t & actual)62   virtual void CompareTags(const std::set<int32_t>& expected,
63                            const camera_metadata_entry_t& actual) {
64     ASSERT_EQ(expected.size(), actual.count);
65     for (size_t i = 0; i < actual.count; ++i) {
66       EXPECT_NE(expected.find(actual.data.i32[i]), expected.end());
67     }
68   }
69 
70   // Device under test.
71   std::unique_ptr<Metadata> dut_;
72   // Mocks.
73   std::unique_ptr<PartialMetadataInterfaceMock> component1_;
74   std::unique_ptr<PartialMetadataInterfaceMock> component2_;
75   // Metadata.
76   std::unique_ptr<android::CameraMetadata> metadata_;
77   std::unique_ptr<android::CameraMetadata> non_empty_metadata_;
78   // An empty vector to use as necessary.
79   std::vector<int32_t> empty_tags_;
80 };
81 
TEST_F(MetadataTest,FillStaticSuccess)82 TEST_F(MetadataTest, FillStaticSuccess) {
83   // Should populate all the component static pieces.
84   EXPECT_CALL(*component1_, PopulateStaticFields(_)).WillOnce(Return(0));
85   EXPECT_CALL(*component2_, PopulateStaticFields(_)).WillOnce(Return(0));
86 
87   // Should populate the meta keys, by polling each component's keys.
88   std::vector<int32_t> static_tags_1({1, 2});
89   std::vector<int32_t> static_tags_2({3, 4});
90   std::vector<int32_t> control_tags_1({5, 6});
91   std::vector<int32_t> control_tags_2({7, 8});
92   std::vector<int32_t> dynamic_tags_1({9, 10});
93   std::vector<int32_t> dynamic_tags_2({11, 12});
94   EXPECT_CALL(*component1_, StaticTags()).WillOnce(Return(static_tags_1));
95   EXPECT_CALL(*component1_, ControlTags()).WillOnce(Return(control_tags_1));
96   EXPECT_CALL(*component1_, DynamicTags()).WillOnce(Return(dynamic_tags_1));
97   EXPECT_CALL(*component2_, StaticTags()).WillOnce(Return(static_tags_2));
98   EXPECT_CALL(*component2_, ControlTags()).WillOnce(Return(control_tags_2));
99   EXPECT_CALL(*component2_, DynamicTags()).WillOnce(Return(dynamic_tags_2));
100 
101   AddComponents();
102   // Should succeed. If it didn't, no reason to continue checking output.
103   ASSERT_EQ(dut_->FillStaticMetadata(metadata_.get()), 0);
104 
105   // Meta keys should be filled correctly.
106   // Note: sets are used here, but it is undefined behavior if
107   // the class has multiple componenets reporting overlapping tags.
108 
109   // Get the expected tags = combined tags of all components.
110   std::set<int32_t> static_tags(static_tags_1.begin(), static_tags_1.end());
111   static_tags.insert(static_tags_2.begin(), static_tags_2.end());
112   std::set<int32_t> control_tags(control_tags_1.begin(), control_tags_1.end());
113   control_tags.insert(control_tags_2.begin(), control_tags_2.end());
114   std::set<int32_t> dynamic_tags(dynamic_tags_1.begin(), dynamic_tags_1.end());
115   dynamic_tags.insert(dynamic_tags_2.begin(), dynamic_tags_2.end());
116 
117   // Static tags includes not only all component static tags, but also
118   // the meta AVAILABLE_*_KEYS (* = [REQUEST, RESULT, CHARACTERISTICS]).
119   static_tags.emplace(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
120   static_tags.emplace(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
121   static_tags.emplace(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
122 
123   // Check against what was filled in in the metadata.
124   CompareTags(static_tags,
125               metadata_->find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS));
126   CompareTags(control_tags,
127               metadata_->find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS));
128   CompareTags(dynamic_tags,
129               metadata_->find(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS));
130 }
131 
TEST_F(MetadataTest,FillStaticFail)132 TEST_F(MetadataTest, FillStaticFail) {
133   int err = -99;
134   // Order undefined, and may or may not exit early; use AtMost.
135   EXPECT_CALL(*component1_, PopulateStaticFields(_))
136       .Times(AtMost(1))
137       .WillOnce(Return(0));
138   EXPECT_CALL(*component2_, PopulateStaticFields(_)).WillOnce(Return(err));
139 
140   // May or may not exit early, may still try to populate meta tags.
141   EXPECT_CALL(*component1_, StaticTags())
142       .Times(AtMost(1))
143       .WillOnce(Return(empty_tags_));
144   EXPECT_CALL(*component1_, ControlTags())
145       .Times(AtMost(1))
146       .WillOnce(Return(empty_tags_));
147   EXPECT_CALL(*component1_, DynamicTags())
148       .Times(AtMost(1))
149       .WillOnce(Return(empty_tags_));
150   EXPECT_CALL(*component2_, StaticTags())
151       .Times(AtMost(1))
152       .WillOnce(Return(empty_tags_));
153   EXPECT_CALL(*component2_, ControlTags())
154       .Times(AtMost(1))
155       .WillOnce(Return(empty_tags_));
156   EXPECT_CALL(*component2_, DynamicTags())
157       .Times(AtMost(1))
158       .WillOnce(Return(empty_tags_));
159 
160   AddComponents();
161   // If any component errors, error should be returned
162   EXPECT_EQ(dut_->FillStaticMetadata(metadata_.get()), err);
163 }
164 
TEST_F(MetadataTest,FillStaticNull)165 TEST_F(MetadataTest, FillStaticNull) {
166   AddComponents();
167   EXPECT_EQ(dut_->FillStaticMetadata(nullptr), -EINVAL);
168 }
169 
TEST_F(MetadataTest,IsValidSuccess)170 TEST_F(MetadataTest, IsValidSuccess) {
171   // Should check if all the component request values are valid.
172   EXPECT_CALL(*component1_, SupportsRequestValues(_)).WillOnce(Return(true));
173   EXPECT_CALL(*component2_, SupportsRequestValues(_)).WillOnce(Return(true));
174 
175   AddComponents();
176   // Should succeed.
177   // Note: getAndLock is a lock against pointer invalidation, not concurrency,
178   // and unlocks on object destruction.
179   EXPECT_TRUE(dut_->IsValidRequest(*non_empty_metadata_));
180 }
181 
TEST_F(MetadataTest,IsValidFail)182 TEST_F(MetadataTest, IsValidFail) {
183   // Should check if all the component request values are valid.
184   // Order undefined, and may or may not exit early; use AtMost.
185   EXPECT_CALL(*component1_, SupportsRequestValues(_))
186       .Times(AtMost(1))
187       .WillOnce(Return(true));
188   EXPECT_CALL(*component2_, SupportsRequestValues(_)).WillOnce(Return(false));
189 
190   AddComponents();
191   // Should fail since one of the components failed.
192   // Note: getAndLock is a lock against pointer invalidation, not concurrency,
193   // and unlocks on object destruction.
194   EXPECT_FALSE(dut_->IsValidRequest(*non_empty_metadata_));
195 }
196 
TEST_F(MetadataTest,IsValidEmpty)197 TEST_F(MetadataTest, IsValidEmpty) {
198   // Setting null settings is a special case indicating to use the
199   // previous (valid) settings. As such it is inherently valid.
200   // Should not try to check any components.
201   EXPECT_CALL(*component1_, SupportsRequestValues(_)).Times(0);
202   EXPECT_CALL(*component2_, SupportsRequestValues(_)).Times(0);
203 
204   AddComponents();
205   EXPECT_TRUE(dut_->IsValidRequest(*metadata_));
206 }
207 
TEST_F(MetadataTest,GetTemplateSuccess)208 TEST_F(MetadataTest, GetTemplateSuccess) {
209   int template_type = 3;
210 
211   // Should check if all the components fill the template successfully.
212   EXPECT_CALL(*component1_, PopulateTemplateRequest(template_type, _))
213       .WillOnce(Return(0));
214   EXPECT_CALL(*component2_, PopulateTemplateRequest(template_type, _))
215       .WillOnce(Return(0));
216 
217   AddComponents();
218   // Should succeed.
219   EXPECT_EQ(dut_->GetRequestTemplate(template_type, metadata_.get()), 0);
220 }
221 
TEST_F(MetadataTest,GetTemplateFail)222 TEST_F(MetadataTest, GetTemplateFail) {
223   int err = -99;
224   int template_type = 3;
225 
226   // Should check if all the components fill the template successfully.
227   // Order undefined, and may or may not exit early; use AtMost.
228   EXPECT_CALL(*component1_, PopulateTemplateRequest(template_type, _))
229       .Times(AtMost(1))
230       .WillOnce(Return(0));
231   EXPECT_CALL(*component2_, PopulateTemplateRequest(template_type, _))
232       .WillOnce(Return(err));
233 
234   AddComponents();
235   // Should fail since one of the components failed.
236   EXPECT_EQ(dut_->GetRequestTemplate(template_type, metadata_.get()), err);
237 }
238 
TEST_F(MetadataTest,GetTemplateNull)239 TEST_F(MetadataTest, GetTemplateNull) {
240   AddComponents();
241   EXPECT_EQ(dut_->GetRequestTemplate(1, nullptr), -EINVAL);
242 }
243 
TEST_F(MetadataTest,GetTemplateInvalid)244 TEST_F(MetadataTest, GetTemplateInvalid) {
245   int template_type = 99;  // Invalid template type.
246 
247   AddComponents();
248   // Should fail fast since template type is invalid.
249   EXPECT_EQ(dut_->GetRequestTemplate(template_type, metadata_.get()), -EINVAL);
250 }
251 
TEST_F(MetadataTest,SetSettingsSuccess)252 TEST_F(MetadataTest, SetSettingsSuccess) {
253   // Should check if all the components set successfully.
254   EXPECT_CALL(*component1_, SetRequestValues(_)).WillOnce(Return(0));
255   EXPECT_CALL(*component2_, SetRequestValues(_)).WillOnce(Return(0));
256 
257   AddComponents();
258   // Should succeed.
259   // Note: getAndLock is a lock against pointer invalidation, not concurrency,
260   // and unlocks on object destruction.
261   EXPECT_EQ(dut_->SetRequestSettings(*non_empty_metadata_), 0);
262 }
263 
TEST_F(MetadataTest,SetSettingsFail)264 TEST_F(MetadataTest, SetSettingsFail) {
265   int err = -99;
266 
267   // Should check if all the components set successfully.
268   // Order undefined, and may or may not exit early; use AtMost.
269   EXPECT_CALL(*component1_, SetRequestValues(_))
270       .Times(AtMost(1))
271       .WillOnce(Return(0));
272   EXPECT_CALL(*component2_, SetRequestValues(_)).WillOnce(Return(err));
273 
274   AddComponents();
275   // Should fail since one of the components failed.
276   // Note: getAndLock is a lock against pointer invalidation, not concurrency,
277   // and unlocks on object destruction.
278   EXPECT_EQ(dut_->SetRequestSettings(*non_empty_metadata_), err);
279 }
280 
TEST_F(MetadataTest,SetSettingsEmpty)281 TEST_F(MetadataTest, SetSettingsEmpty) {
282   // Setting null settings is a special case indicating to use the
283   // previous settings. Should not try to set any components.
284   EXPECT_CALL(*component1_, SetRequestValues(_)).Times(0);
285   EXPECT_CALL(*component2_, SetRequestValues(_)).Times(0);
286 
287   AddComponents();
288   // Should succeed.
289   EXPECT_EQ(dut_->SetRequestSettings(*metadata_), 0);
290 }
291 
TEST_F(MetadataTest,FillResultSuccess)292 TEST_F(MetadataTest, FillResultSuccess) {
293   // Should check if all the components fill results successfully.
294   EXPECT_CALL(*component1_, PopulateDynamicFields(_)).WillOnce(Return(0));
295   EXPECT_CALL(*component2_, PopulateDynamicFields(_)).WillOnce(Return(0));
296 
297   AddComponents();
298   // Should succeed.
299   EXPECT_EQ(dut_->FillResultMetadata(metadata_.get()), 0);
300 }
301 
TEST_F(MetadataTest,FillResultFail)302 TEST_F(MetadataTest, FillResultFail) {
303   int err = -99;
304 
305   // Should check if all the components fill results successfully.
306   // Order undefined, and may or may not exit early; use AtMost.
307   EXPECT_CALL(*component1_, PopulateDynamicFields(_))
308       .Times(AtMost(1))
309       .WillOnce(Return(0));
310   EXPECT_CALL(*component2_, PopulateDynamicFields(_)).WillOnce(Return(err));
311 
312   AddComponents();
313   // Should fail since one of the components failed.
314   EXPECT_EQ(dut_->FillResultMetadata(metadata_.get()), err);
315 }
316 
TEST_F(MetadataTest,FillResultNull)317 TEST_F(MetadataTest, FillResultNull) {
318   AddComponents();
319   EXPECT_EQ(dut_->FillResultMetadata(nullptr), -EINVAL);
320 }
321 
322 }  // namespace v4l2_camera_hal
323