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