Refactor static functions.
Common static functions for manipulating metadata moved
from patial_metadata_interface to metadata_common.h
Common static functions for comparing equivalence with
metadata for tests moved to test_common.h
BUG: 30140438
TEST: Unit tests pass
Change-Id: I4310b4ff05bdd68f7f92f533028989914d0f4c82
diff --git a/modules/camera/3_4/metadata/control.h b/modules/camera/3_4/metadata/control.h
index db19b1d..4b4adcf 100644
--- a/modules/camera/3_4/metadata/control.h
+++ b/modules/camera/3_4/metadata/control.h
@@ -22,6 +22,7 @@
#include <system/camera_metadata.h>
#include "../common.h"
+#include "metadata_common.h"
#include "tagged_partial_metadata.h"
namespace v4l2_camera_hal {
diff --git a/modules/camera/3_4/metadata/control_test.cpp b/modules/camera/3_4/metadata/control_test.cpp
index 6e45d02..ef4b6af 100644
--- a/modules/camera/3_4/metadata/control_test.cpp
+++ b/modules/camera/3_4/metadata/control_test.cpp
@@ -22,6 +22,9 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include "metadata_common.h"
+#include "test_common.h"
+
using testing::AtMost;
using testing::Return;
using testing::ReturnRef;
@@ -48,37 +51,6 @@
virtual void SetUp() {
control_.reset(new MockControl<uint8_t>(control_tag_));
}
- // Check that metadata of a given tag matches expectations.
- virtual void ExpectMetadataEq(const android::CameraMetadata& metadata,
- int32_t tag, const uint8_t* expected,
- size_t size) {
- camera_metadata_ro_entry_t entry = metadata.find(tag);
- ASSERT_EQ(entry.count, size);
- for (size_t i = 0; i < size; ++i) {
- EXPECT_EQ(entry.data.u8[i], expected[i]);
- }
- }
- virtual void ExpectMetadataEq(const android::CameraMetadata& metadata,
- int32_t tag, const int32_t* expected,
- size_t size) {
- camera_metadata_ro_entry_t entry = metadata.find(tag);
- ASSERT_EQ(entry.count, size);
- for (size_t i = 0; i < size; ++i) {
- EXPECT_EQ(entry.data.i32[i], expected[i]);
- }
- }
- // Single item.
- template <typename T>
- void ExpectMetadataEq(const android::CameraMetadata& metadata, int32_t tag,
- T expected) {
- ExpectMetadataEq(metadata, tag, &expected, 1);
- }
- // Vector of items.
- template <typename T>
- void ExpectMetadataEq(const android::CameraMetadata& metadata, int32_t tag,
- const std::vector<T>& expected) {
- ExpectMetadataEq(metadata, tag, expected.data(), expected.size());
- }
std::unique_ptr<MockControl<uint8_t>> control_;
@@ -128,7 +100,7 @@
TEST_F(ControlTest, SupportsRequest) {
android::CameraMetadata metadata;
uint8_t test_option = 123;
- ASSERT_EQ(metadata.update(control_tag_, &test_option, 1), android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
EXPECT_CALL(*control_, IsSupported(test_option)).WillOnce(Return(true));
EXPECT_EQ(control_->SupportsRequestValues(metadata), true);
@@ -137,9 +109,7 @@
TEST_F(ControlTest, ArraySupportsRequest) {
android::CameraMetadata metadata;
std::array<uint8_t, 2> test_option = {{12, 34}};
- ASSERT_EQ(
- metadata.update(control_tag_, test_option.data(), test_option.size()),
- android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
MockControl<std::array<uint8_t, 2>> test_control(control_tag_);
EXPECT_CALL(test_control, IsSupported(test_option)).WillOnce(Return(true));
@@ -149,7 +119,7 @@
TEST_F(ControlTest, SupportsRequestFail) {
android::CameraMetadata metadata;
uint8_t test_option = 123;
- ASSERT_EQ(metadata.update(control_tag_, &test_option, 1), android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
EXPECT_CALL(*control_, IsSupported(test_option)).WillOnce(Return(false));
EXPECT_EQ(control_->SupportsRequestValues(metadata), false);
@@ -159,8 +129,7 @@
// Start with a request for multiple values.
android::CameraMetadata metadata;
std::vector<uint8_t> test_data = {1, 2, 3};
- ASSERT_EQ(metadata.update(control_tag_, test_data.data(), test_data.size()),
- android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_data), 0);
EXPECT_EQ(control_->SupportsRequestValues(metadata), false);
}
@@ -168,7 +137,7 @@
// Start with a request for a single (non-array) value.
android::CameraMetadata metadata;
uint8_t test_data = 1;
- ASSERT_EQ(metadata.update(control_tag_, &test_data, 1), android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_data), 0);
MockControl<std::array<uint8_t, 2>> test_control(control_tag_);
EXPECT_EQ(test_control.SupportsRequestValues(metadata), false);
@@ -182,7 +151,7 @@
TEST_F(ControlTest, SetRequest) {
android::CameraMetadata metadata(1);
uint8_t test_option = 123;
- ASSERT_EQ(metadata.update(control_tag_, &test_option, 1), android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
EXPECT_CALL(*control_, SetValue(test_option)).WillOnce(Return(0));
// Make the request.
@@ -192,9 +161,7 @@
TEST_F(ControlTest, ArraySetRequest) {
android::CameraMetadata metadata;
std::array<uint8_t, 2> test_option = {{12, 34}};
- ASSERT_EQ(
- metadata.update(control_tag_, test_option.data(), test_option.size()),
- android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
MockControl<std::array<uint8_t, 2>> test_control(control_tag_);
EXPECT_CALL(test_control, SetValue(test_option)).WillOnce(Return(0));
@@ -204,7 +171,7 @@
TEST_F(ControlTest, SetRequestFail) {
android::CameraMetadata metadata(1);
uint8_t test_option = 123;
- ASSERT_EQ(metadata.update(control_tag_, &test_option, 1), android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
int err = -99;
EXPECT_CALL(*control_, SetValue(test_option)).WillOnce(Return(err));
@@ -215,8 +182,7 @@
// Start with a request for multiple values.
android::CameraMetadata metadata;
std::vector<uint8_t> test_data = {1, 2, 3};
- ASSERT_EQ(metadata.update(control_tag_, test_data.data(), test_data.size()),
- android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_data), 0);
EXPECT_EQ(control_->SetRequestValues(metadata), -EINVAL);
}
@@ -224,7 +190,7 @@
// Start with a request for a single (non-array) value.
android::CameraMetadata metadata;
uint8_t test_data = 1;
- ASSERT_EQ(metadata.update(control_tag_, &test_data, 1), android::OK);
+ ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_data), 0);
MockControl<std::array<uint8_t, 2>> test_control(control_tag_);
EXPECT_EQ(test_control.SetRequestValues(metadata), -EINVAL);
diff --git a/modules/camera/3_4/metadata/fixed_property_test.cpp b/modules/camera/3_4/metadata/fixed_property_test.cpp
index cf7cf10..07a1bce 100644
--- a/modules/camera/3_4/metadata/fixed_property_test.cpp
+++ b/modules/camera/3_4/metadata/fixed_property_test.cpp
@@ -24,6 +24,8 @@
#include <gtest/gtest.h>
#include "array_vector.h"
+#include "metadata_common.h"
+#include "test_common.h"
using testing::AtMost;
using testing::Return;
@@ -67,9 +69,7 @@
// Should only have added 1 entry.
EXPECT_EQ(metadata.entryCount(), 1);
// Should have added the right entry.
- camera_metadata_entry_t entry = metadata.find(int_tag_);
- ASSERT_EQ(entry.count, 1);
- EXPECT_EQ(*entry.data.i32, data);
+ ExpectMetadataEq(metadata, int_tag_, data);
}
TEST_F(FixedPropertyTest, PopulateStaticVector) {
@@ -85,11 +85,7 @@
// Should only have added 1 entry.
EXPECT_EQ(metadata.entryCount(), 1);
// Should have added the right entry.
- camera_metadata_entry_t entry = metadata.find(float_tag_);
- ASSERT_EQ(entry.count, data.size());
- for (size_t i = 0; i < data.size(); ++i) {
- EXPECT_EQ(entry.data.f[i], data[i]);
- }
+ ExpectMetadataEq(metadata, float_tag_, data);
}
TEST_F(FixedPropertyTest, PopulateStaticArray) {
@@ -105,11 +101,7 @@
// Should only have added 1 entry.
EXPECT_EQ(metadata.entryCount(), 1);
// Should have added the right entry.
- camera_metadata_entry_t entry = metadata.find(float_tag_);
- ASSERT_EQ(entry.count, data.size());
- for (size_t i = 0; i < data.size(); ++i) {
- EXPECT_EQ(entry.data.f[i], data[i]);
- }
+ ExpectMetadataEq(metadata, float_tag_, data);
}
TEST_F(FixedPropertyTest, PopulateStaticArrayVector) {
@@ -127,11 +119,7 @@
// Should only have added 1 entry.
EXPECT_EQ(metadata.entryCount(), 1);
// Should have added the right entry.
- camera_metadata_entry_t entry = metadata.find(byte_tag_);
- ASSERT_EQ(entry.count, data.total_num_elements());
- for (size_t i = 0; i < data.total_num_elements(); ++i) {
- EXPECT_EQ(entry.data.u8[i], data.data()[i]);
- }
+ ExpectMetadataEq(metadata, byte_tag_, data);
}
TEST_F(FixedPropertyTest, PopulateDynamic) {
diff --git a/modules/camera/3_4/metadata/metadata_common.h b/modules/camera/3_4/metadata/metadata_common.h
new file mode 100644
index 0000000..55f8a6f
--- /dev/null
+++ b/modules/camera/3_4/metadata/metadata_common.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef V4L2_CAMERA_HAL_METADATA_METADATA_COMMON_H_
+#define V4L2_CAMERA_HAL_METADATA_METADATA_COMMON_H_
+
+#include <array>
+#include <vector>
+
+#include <camera/CameraMetadata.h>
+
+#include "array_vector.h"
+
+namespace v4l2_camera_hal {
+
+// Templated helper functions effectively extending android::CameraMetadata.
+// Will cause a compile-time errors if CameraMetadata doesn't support
+// using the templated type. Templates are provided to extend this support
+// to std::arrays, std::vectors, and ArrayVectors of supported types as
+// appropriate.
+
+// UpdateMetadata(metadata, tag, data):
+//
+// Updates the entry for |tag| in |metadata| (functionally similar to
+// android::CameraMetadata::update).
+//
+// Args:
+// metadata: the android::CameraMetadata to update.
+// tag: the tag within |metadata| to update.
+// data: A reference to the data to update |tag| with.
+//
+// Returns:
+// 0: Success.
+// -ENODEV: The type of |data| does not match the expected type for |tag|,
+// or another error occured. Note: no errors are given for updating a
+// metadata entry with an incorrect amount of data (e.g. filling a tag
+// that expects to have only one value with multiple values), as this
+// information is not encoded in the type associated with the tag by
+// get_camera_metadata_tag_type (from <system/camera_metadata.h>).
+
+// Generic (pointer & size).
+template <typename T>
+static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
+ const T* data, size_t count) {
+ int res = metadata->update(tag, data, count);
+ if (res) {
+ HAL_LOGE("Failed to update metadata tag %d", tag);
+ return -ENODEV;
+ }
+ return 0;
+}
+
+// Generic (single item reference).
+template <typename T>
+static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
+ const T& val) {
+ return UpdateMetadata(metadata, tag, &val, 1);
+}
+
+// Specialization for vectors.
+template <typename T>
+static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
+ const std::vector<T>& val) {
+ return UpdateMetadata(metadata, tag, val.data(), val.size());
+}
+
+// Specialization for arrays.
+template <typename T, size_t N>
+static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
+ const std::array<T, N>& val) {
+ return UpdateMetadata(metadata, tag, val.data(), N);
+}
+
+// Specialization for ArrayVectors.
+template <typename T, size_t N>
+static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
+ const ArrayVector<T, N>& val) {
+ return UpdateMetadata(metadata, tag, val.data(), val.total_num_elements());
+}
+
+// Specialization for vectors of arrays.
+template <typename T, size_t N>
+static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
+ const std::vector<std::array<T, N>>& val) {
+ // Convert to array vector so we know all the elements are contiguous.
+ ArrayVector<T, N> array_vector;
+ for (const auto& array : val) {
+ array_vector.push_back(array);
+ }
+ return UpdateMetadata(metadata, tag, array_vector);
+}
+
+// GetDataPointer(entry, val)
+//
+// A helper for other methods in this file.
+// Gets the data pointer of a given metadata entry into |*val|.
+
+static void GetDataPointer(camera_metadata_ro_entry_t& entry,
+ const uint8_t** val) {
+ *val = entry.data.u8;
+}
+
+static void GetDataPointer(camera_metadata_ro_entry_t& entry,
+ const int32_t** val) {
+ *val = entry.data.i32;
+}
+
+static void GetDataPointer(camera_metadata_ro_entry_t& entry,
+ const float** val) {
+ *val = entry.data.f;
+}
+
+static void GetDataPointer(camera_metadata_ro_entry_t& entry,
+ const int64_t** val) {
+ *val = entry.data.i64;
+}
+
+static void GetDataPointer(camera_metadata_ro_entry_t& entry,
+ const double** val) {
+ *val = entry.data.d;
+}
+
+static void GetDataPointer(camera_metadata_ro_entry_t& entry,
+ const camera_metadata_rational_t** val) {
+ *val = entry.data.r;
+}
+
+// SingleTagValue(metadata, tag, val)
+//
+// Get the value of the |tag| entry in |metadata|.
+// |tag| is expected to refer to an entry with a single item
+// of the templated type (a "single item" is exactly N values
+// if the templated type is an array of size N). An error will be
+// returned if it the wrong number of items are present.
+//
+// Returns:
+// -ENOENT: The tag couldn't be found or was empty.
+// -EINVAL: The tag contained more than one item.
+// -ENODEV: The tag claims to be non-empty, but the data pointer is null.
+// 0: Success. |*val| will contain the value for |tag|.
+
+// Singleton.
+template <typename T>
+static int SingleTagValue(const android::CameraMetadata& metadata, int32_t tag,
+ T* val) {
+ camera_metadata_ro_entry_t entry = metadata.find(tag);
+ if (entry.count == 0) {
+ HAL_LOGE("Metadata tag %d is empty.", tag);
+ return -ENOENT;
+ } else if (entry.count != 1) {
+ HAL_LOGE(
+ "Error: expected metadata tag %d to contain exactly 1 value "
+ "(had %d).",
+ tag, entry.count);
+ return -EINVAL;
+ }
+ const T* data = nullptr;
+ GetDataPointer(entry, &data);
+ if (data == nullptr) {
+ HAL_LOGE("Metadata tag %d is empty.", tag);
+ return -ENODEV;
+ }
+ *val = *data;
+ return 0;
+}
+
+// Specialization for std::array.
+template <typename T, size_t N>
+static int SingleTagValue(const android::CameraMetadata& metadata, int32_t tag,
+ std::array<T, N>* val) {
+ camera_metadata_ro_entry_t entry = metadata.find(tag);
+ if (entry.count == 0) {
+ HAL_LOGE("Metadata tag %d is empty.", tag);
+ return -ENOENT;
+ } else if (entry.count != N) {
+ HAL_LOGE(
+ "Error: expected metadata tag %d to contain a single array of "
+ "exactly %d values (had %d).",
+ tag, N, entry.count);
+ return -EINVAL;
+ }
+ const T* data = nullptr;
+ GetDataPointer(entry, &data);
+ if (data == nullptr) {
+ HAL_LOGE("Metadata tag %d is empty.", tag);
+ return -ENODEV;
+ }
+ // Fill in the array.
+ for (size_t i = 0; i < N; ++i) {
+ (*val)[i] = data[i];
+ }
+ return 0;
+}
+
+} // namespace v4l2_camera_hal
+
+#endif // V4L2_CAMERA_HAL_METADATA_METADATA_COMMON_H_
diff --git a/modules/camera/3_4/metadata/optioned_control.h b/modules/camera/3_4/metadata/optioned_control.h
index bf8ec44..10052cc 100644
--- a/modules/camera/3_4/metadata/optioned_control.h
+++ b/modules/camera/3_4/metadata/optioned_control.h
@@ -24,6 +24,7 @@
#include "../common.h"
#include "control.h"
+#include "metadata_common.h"
namespace v4l2_camera_hal {
@@ -68,7 +69,7 @@
HAL_LOG_ENTER();
// Populate the available options.
- return Control<T>::UpdateMetadata(metadata, OptionsTag(), options_);
+ return UpdateMetadata(metadata, OptionsTag(), options_);
}
template <typename T>
diff --git a/modules/camera/3_4/metadata/optioned_control_test.cpp b/modules/camera/3_4/metadata/optioned_control_test.cpp
index 8fcc1cb..1cfccbf 100644
--- a/modules/camera/3_4/metadata/optioned_control_test.cpp
+++ b/modules/camera/3_4/metadata/optioned_control_test.cpp
@@ -20,6 +20,8 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include "test_common.h"
+
using testing::AtMost;
using testing::Return;
using testing::ReturnRef;
@@ -50,37 +52,6 @@
control_.reset(
new MockOptionedControl<uint8_t>(control_tag_, options_tag_, options_));
}
- // Check that metadata of a given tag matches expectations.
- virtual void ExpectMetadataEq(const android::CameraMetadata& metadata,
- int32_t tag, const uint8_t* expected,
- size_t size) {
- camera_metadata_ro_entry_t entry = metadata.find(tag);
- ASSERT_EQ(entry.count, size);
- for (size_t i = 0; i < size; ++i) {
- EXPECT_EQ(entry.data.u8[i], expected[i]);
- }
- }
- virtual void ExpectMetadataEq(const android::CameraMetadata& metadata,
- int32_t tag, const int32_t* expected,
- size_t size) {
- camera_metadata_ro_entry_t entry = metadata.find(tag);
- ASSERT_EQ(entry.count, size);
- for (size_t i = 0; i < size; ++i) {
- EXPECT_EQ(entry.data.i32[i], expected[i]);
- }
- }
- // Single item.
- template <typename T>
- void ExpectMetadataEq(const android::CameraMetadata& metadata, int32_t tag,
- T expected) {
- ExpectMetadataEq(metadata, tag, &expected, 1);
- }
- // Vector of items.
- template <typename T>
- void ExpectMetadataEq(const android::CameraMetadata& metadata, int32_t tag,
- const std::vector<T>& expected) {
- ExpectMetadataEq(metadata, tag, expected.data(), expected.size());
- }
std::unique_ptr<OptionedControl<uint8_t>> control_;
diff --git a/modules/camera/3_4/metadata/partial_metadata_interface.h b/modules/camera/3_4/metadata/partial_metadata_interface.h
index 09bfebc..d1a434f 100644
--- a/modules/camera/3_4/metadata/partial_metadata_interface.h
+++ b/modules/camera/3_4/metadata/partial_metadata_interface.h
@@ -56,159 +56,6 @@
// tags indicate no change. If |metadata| is empty no controls should
// be changed.
virtual int SetRequestValues(const android::CameraMetadata& metadata) = 0;
-
- protected:
- // Templated helper function to update a single entry of some metadata.
- // Will cause a compile-time error if CameraMetadata doesn't support
- // updating the given type. An error will be returned if the data type
- // does not match the expected type for the tag. No errors are given
- // for updating a metadata entry with the incorrect amount of data,
- // as this information is not encoded in the type associated with the tag
- // by get_camera_metadata_tag_type (from <system/camera_metadata.h>).
- // Generic (pointer & size).
- template <typename T>
- static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
- const T* data, size_t count) {
- int res = metadata->update(tag, data, count);
- if (res) {
- HAL_LOGE("Failed to update metadata tag %d", tag);
- return -ENODEV;
- }
- return 0;
- }
-
- // Generic (single item reference).
- template <typename T>
- static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
- const T& val) {
- return UpdateMetadata(metadata, tag, &val, 1);
- }
-
- // Specialization for vectors.
- template <typename T>
- static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
- const std::vector<T>& val) {
- return UpdateMetadata(metadata, tag, val.data(), val.size());
- }
-
- // Specialization for arrays.
- template <typename T, size_t N>
- static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
- const std::array<T, N>& val) {
- return UpdateMetadata(metadata, tag, val.data(), N);
- }
-
- // Specialization for ArrayVectors.
- template <typename T, size_t N>
- static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
- const ArrayVector<T, N>& val) {
- return UpdateMetadata(metadata, tag, val.data(), val.total_num_elements());
- }
-
- // Specialization for vectors of arrays.
- template <typename T, size_t N>
- static int UpdateMetadata(android::CameraMetadata* metadata, int32_t tag,
- const std::vector<std::array<T, N>>& val) {
- // Convert to array vector so we know all the elements are contiguous.
- ArrayVector<T, N> array_vector;
- for (const auto& array : val) {
- array_vector.push_back(array);
- }
- return UpdateMetadata(metadata, tag, array_vector);
- }
-
- // Get the data pointer of a given metadata entry. Enforces that |val| must
- // be a type supported by camera_metadata.
-
- static void GetDataPointer(camera_metadata_ro_entry_t& entry,
- const uint8_t** val) {
- *val = entry.data.u8;
- }
-
- static void GetDataPointer(camera_metadata_ro_entry_t& entry,
- const int32_t** val) {
- *val = entry.data.i32;
- }
-
- static void GetDataPointer(camera_metadata_ro_entry_t& entry,
- const float** val) {
- *val = entry.data.f;
- }
-
- static void GetDataPointer(camera_metadata_ro_entry_t& entry,
- const int64_t** val) {
- *val = entry.data.i64;
- }
-
- static void GetDataPointer(camera_metadata_ro_entry_t& entry,
- const double** val) {
- *val = entry.data.d;
- }
-
- static void GetDataPointer(camera_metadata_ro_entry_t& entry,
- const camera_metadata_rational_t** val) {
- *val = entry.data.r;
- }
-
- // Get a tag value that is expected to be a single item.
- // Returns:
- // -ENOENT: The tag couldn't be found or was empty.
- // -EINVAL: The tag contained more than one item.
- // -ENODEV: The tag claims to be non-empty, but the data pointer is null.
- // 0: Success. |*val| will contain the value for |tag|.
-
- // Generic (one of the types supported by TagValue above).
- template <typename T>
- static int SingleTagValue(const android::CameraMetadata& metadata,
- int32_t tag, T* val) {
- camera_metadata_ro_entry_t entry = metadata.find(tag);
- if (entry.count == 0) {
- HAL_LOGE("Metadata tag %d is empty.", tag);
- return -ENOENT;
- } else if (entry.count != 1) {
- HAL_LOGE(
- "Error: expected metadata tag %d to contain exactly 1 value "
- "(had %d).",
- tag, entry.count);
- return -EINVAL;
- }
- const T* data = nullptr;
- GetDataPointer(entry, &data);
- if (data == nullptr) {
- HAL_LOGE("Metadata tag %d is empty.", tag);
- return -ENODEV;
- }
- *val = *data;
- return 0;
- }
-
- // Specialization for std::array (of the types supported by TagValue above).
- template <typename T, size_t N>
- static int SingleTagValue(const android::CameraMetadata& metadata,
- int32_t tag, std::array<T, N>* val) {
- camera_metadata_ro_entry_t entry = metadata.find(tag);
- if (entry.count == 0) {
- HAL_LOGE("Metadata tag %d is empty.", tag);
- return -ENOENT;
- } else if (entry.count != N) {
- HAL_LOGE(
- "Error: expected metadata tag %d to contain a single array of "
- "exactly %d values (had %d).",
- tag, N, entry.count);
- return -EINVAL;
- }
- const T* data = nullptr;
- GetDataPointer(entry, &data);
- if (data == nullptr) {
- HAL_LOGE("Metadata tag %d is empty.", tag);
- return -ENODEV;
- }
- // Fill in the array.
- for (size_t i = 0; i < N; ++i) {
- (*val)[i] = data[i];
- }
- return 0;
- }
};
} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/property.h b/modules/camera/3_4/metadata/property.h
index 78cd2fa..a3ed6bf 100644
--- a/modules/camera/3_4/metadata/property.h
+++ b/modules/camera/3_4/metadata/property.h
@@ -18,6 +18,7 @@
#define V4L2_CAMERA_HAL_METADATA_PROPERTY_H_
#include "../common.h"
+#include "metadata_common.h"
#include "tagged_partial_metadata.h"
namespace v4l2_camera_hal {
diff --git a/modules/camera/3_4/metadata/test_common.h b/modules/camera/3_4/metadata/test_common.h
new file mode 100644
index 0000000..6cbd611
--- /dev/null
+++ b/modules/camera/3_4/metadata/test_common.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef V4L2_CAMERA_HAL_METADATA_TEST_COMMON_H_
+#define V4L2_CAMERA_HAL_METADATA_TEST_COMMON_H_
+
+#include <array>
+#include <vector>
+
+#include <camera/CameraMetadata.h>
+#include <gtest/gtest.h>
+
+#include "array_vector.h"
+#include "metadata_common.h"
+
+namespace v4l2_camera_hal {
+
+// Check that metadata of a given tag matches expectations.
+// Generic.
+template <typename T>
+static void ExpectMetadataEq(const android::CameraMetadata& metadata,
+ int32_t tag, const T* expected, size_t size) {
+ camera_metadata_ro_entry_t entry = metadata.find(tag);
+ ASSERT_EQ(entry.count, size);
+ const T* data = nullptr;
+ GetDataPointer(entry, &data);
+ ASSERT_NE(data, nullptr);
+ for (size_t i = 0; i < size; ++i) {
+ EXPECT_EQ(data[i], expected[i]);
+ }
+}
+
+// Single item.
+template <typename T>
+static void ExpectMetadataEq(const android::CameraMetadata& metadata,
+ int32_t tag, T expected) {
+ ExpectMetadataEq(metadata, tag, &expected, 1);
+}
+
+// Vector of items.
+template <typename T>
+static void ExpectMetadataEq(const android::CameraMetadata& metadata,
+ int32_t tag, const std::vector<T>& expected) {
+ ExpectMetadataEq(metadata, tag, expected.data(), expected.size());
+}
+
+// Array of items.
+template <typename T, size_t N>
+static void ExpectMetadataEq(const android::CameraMetadata& metadata,
+ int32_t tag, const std::array<T, N>& expected) {
+ ExpectMetadataEq(metadata, tag, expected.data(), N);
+}
+
+// ArrayVector.
+template <typename T, size_t N>
+static void ExpectMetadataEq(const android::CameraMetadata& metadata,
+ int32_t tag, const ArrayVector<T, N>& expected) {
+ ExpectMetadataEq(metadata, tag, expected.data(),
+ expected.total_num_elements());
+}
+
+// Vector of arrays.
+template <typename T, size_t N>
+static int ExpectMetadataEq(const android::CameraMetadata& metadata,
+ int32_t tag,
+ const std::vector<std::array<T, N>>& expected) {
+ // Convert to array vector so we know all the elements are contiguous.
+ ArrayVector<T, N> array_vector;
+ for (const auto& array : expected) {
+ array_vector.push_back(array);
+ }
+ ExpectMetadataEq(metadata, tag, array_vector);
+}
+
+} // namespace v4l2_camera_hal
+
+#endif // V4L2_CAMERA_HAL_METADATA_TEST_COMMON_H_