/* * 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. */ #include "control.h" #include <camera/CameraMetadata.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include "control_delegate_interface_mock.h" #include "control_options_interface_mock.h" #include "metadata_common.h" #include "test_common.h" using testing::AtMost; using testing::Expectation; using testing::Return; using testing::SetArgPointee; using testing::Test; using testing::_; namespace v4l2_camera_hal { class ControlTest : public Test { protected: virtual void SetUp() { mock_delegate_.reset(new ControlDelegateInterfaceMock<uint8_t>()); mock_options_.reset(new ControlOptionsInterfaceMock<uint8_t>()); // Nullify control so an error will be thrown if a test doesn't call // PrepareControl. control_.reset(); } virtual void PrepareControl() { // Use this method after all the EXPECT_CALLs to pass ownership of the mocks // to the device. std::unique_ptr<TaggedControlDelegate<uint8_t>> delegate = std::make_unique<TaggedControlDelegate<uint8_t>>( delegate_tag_, std::move(mock_delegate_)); std::unique_ptr<TaggedControlOptions<uint8_t>> options = std::make_unique<TaggedControlOptions<uint8_t>>( report_options_ ? options_tag_ : DO_NOT_REPORT_OPTIONS, std::move(mock_options_)); if (use_options_) { control_.reset( new Control<uint8_t>(std::move(delegate), std::move(options))); } else { control_.reset(new Control<uint8_t>(std::move(delegate))); } } virtual void ExpectTags() { if (use_options_ && report_options_) { ASSERT_EQ(control_->StaticTags().size(), 1u); EXPECT_EQ(control_->StaticTags()[0], options_tag_); } else { EXPECT_TRUE(control_->StaticTags().empty()); } // Controls use the same delgate, and thus tag, for getting and setting. ASSERT_EQ(control_->ControlTags().size(), 1u); EXPECT_EQ(control_->ControlTags()[0], delegate_tag_); ASSERT_EQ(control_->DynamicTags().size(), 1u); EXPECT_EQ(control_->DynamicTags()[0], delegate_tag_); } virtual void ExpectOptions(const std::vector<uint8_t>& options) { // Options should be available. android::CameraMetadata metadata; ASSERT_EQ(control_->PopulateStaticFields(&metadata), 0); if (use_options_ && report_options_) { EXPECT_EQ(metadata.entryCount(), 1u); ExpectMetadataEq(metadata, options_tag_, options); } else { EXPECT_EQ(metadata.entryCount(), 0u); // Shouldn't be expecting any options. EXPECT_TRUE(options.empty()); } } virtual void ExpectValue(uint8_t value) { android::CameraMetadata metadata; ASSERT_EQ(control_->PopulateDynamicFields(&metadata), 0); EXPECT_EQ(metadata.entryCount(), 1u); ExpectMetadataEq(metadata, delegate_tag_, value); } std::unique_ptr<Control<uint8_t>> control_; std::unique_ptr<ControlDelegateInterfaceMock<uint8_t>> mock_delegate_; std::unique_ptr<ControlOptionsInterfaceMock<uint8_t>> mock_options_; bool use_options_ = true; bool report_options_ = true; // Need tags that match the data type (uint8_t) being passed. const int32_t delegate_tag_ = ANDROID_COLOR_CORRECTION_ABERRATION_MODE; const int32_t options_tag_ = ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES; }; TEST_F(ControlTest, Tags) { PrepareControl(); ExpectTags(); } TEST_F(ControlTest, TagsNoOptions) { use_options_ = false; PrepareControl(); ExpectTags(); } TEST_F(ControlTest, TagsUnreportedOptions) { report_options_ = false; PrepareControl(); ExpectTags(); } TEST_F(ControlTest, PopulateStatic) { std::vector<uint8_t> expected{1, 10, 20}; EXPECT_CALL(*mock_options_, MetadataRepresentation()) .WillOnce(Return(expected)); PrepareControl(); ExpectOptions(expected); } TEST_F(ControlTest, PopulateStaticNoOptions) { use_options_ = false; PrepareControl(); ExpectOptions({}); } TEST_F(ControlTest, PopulateStaticUnreportedOptions) { report_options_ = false; PrepareControl(); ExpectOptions({}); } TEST_F(ControlTest, PopulateDynamic) { uint8_t test_option = 99; EXPECT_CALL(*mock_delegate_, GetValue(_)) .WillOnce(DoAll(SetArgPointee<0>(test_option), Return(0))); PrepareControl(); ExpectValue(test_option); } TEST_F(ControlTest, PopulateDynamicNoOptions) { // Lack of options shouldn't change anything for PopulateDynamic. use_options_ = false; uint8_t test_option = 99; EXPECT_CALL(*mock_delegate_, GetValue(_)) .WillOnce(DoAll(SetArgPointee<0>(test_option), Return(0))); PrepareControl(); ExpectValue(test_option); } TEST_F(ControlTest, PopulateDynamicUnreportedOptions) { // Lack of reported options shouldn't change anything for PopulateDynamic. report_options_ = false; uint8_t test_option = 99; EXPECT_CALL(*mock_delegate_, GetValue(_)) .WillOnce(DoAll(SetArgPointee<0>(test_option), Return(0))); PrepareControl(); ExpectValue(test_option); } TEST_F(ControlTest, PopulateDynamicFail) { int err = -99; EXPECT_CALL(*mock_delegate_, GetValue(_)).WillOnce(Return(err)); PrepareControl(); android::CameraMetadata metadata; EXPECT_EQ(control_->PopulateDynamicFields(&metadata), err); // Should not have added an entry. EXPECT_TRUE(metadata.isEmpty()); } TEST_F(ControlTest, PopulateTemplate) { int template_type = 3; uint8_t default_value = 123; EXPECT_CALL(*mock_options_, DefaultValueForTemplate(template_type, _)) .WillOnce(DoAll(SetArgPointee<1>(default_value), Return(0))); PrepareControl(); android::CameraMetadata metadata; EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), 0); ExpectMetadataEq(metadata, delegate_tag_, default_value); } TEST_F(ControlTest, PopulateTemplateFail) { int template_type = 3; int err = 10; EXPECT_CALL(*mock_options_, DefaultValueForTemplate(template_type, _)) .WillOnce(Return(err)); PrepareControl(); android::CameraMetadata metadata; EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), err); } TEST_F(ControlTest, PopulateTemplateOptionless) { use_options_ = false; int template_type = 3; uint8_t value = 12; // Should use delegate instead of options if no options. EXPECT_CALL(*mock_delegate_, GetValue(_)) .WillOnce(DoAll(SetArgPointee<0>(value), Return(0))); PrepareControl(); android::CameraMetadata metadata; EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), 0); ExpectMetadataEq(metadata, delegate_tag_, value); } TEST_F(ControlTest, PopulateTemplateOptionlessFail) { use_options_ = false; int template_type = 3; int err = 10; // Should use delegate instead of options if no options. EXPECT_CALL(*mock_delegate_, GetValue(_)).WillOnce(Return(err)); PrepareControl(); android::CameraMetadata metadata; EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), err); } TEST_F(ControlTest, PopulateTemplateUnreportedOptions) { report_options_ = false; int template_type = 3; uint8_t default_value = 123; // Unreported options should behave just like reported ones for templating. EXPECT_CALL(*mock_options_, DefaultValueForTemplate(template_type, _)) .WillOnce(DoAll(SetArgPointee<1>(default_value), Return(0))); PrepareControl(); android::CameraMetadata metadata; EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), 0); ExpectMetadataEq(metadata, delegate_tag_, default_value); } TEST_F(ControlTest, PopulateTemplateUnreportedOptionsFail) { report_options_ = false; int template_type = 3; int err = 10; // Unreported options should behave just like reported ones for templating. EXPECT_CALL(*mock_options_, DefaultValueForTemplate(template_type, _)) .WillOnce(Return(err)); PrepareControl(); android::CameraMetadata metadata; EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), err); } TEST_F(ControlTest, SupportsRequest) { android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); EXPECT_CALL(*mock_options_, IsSupported(test_option)).WillOnce(Return(true)); PrepareControl(); EXPECT_EQ(control_->SupportsRequestValues(metadata), true); } TEST_F(ControlTest, SupportsRequestNoOptions) { use_options_ = false; android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); PrepareControl(); EXPECT_EQ(control_->SupportsRequestValues(metadata), true); } TEST_F(ControlTest, SupportsRequestUnreportedOptions) { report_options_ = false; android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); EXPECT_CALL(*mock_options_, IsSupported(test_option)).WillOnce(Return(true)); PrepareControl(); EXPECT_EQ(control_->SupportsRequestValues(metadata), true); } TEST_F(ControlTest, SupportsRequestFail) { android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); EXPECT_CALL(*mock_options_, IsSupported(test_option)).WillOnce(Return(false)); PrepareControl(); EXPECT_EQ(control_->SupportsRequestValues(metadata), false); } TEST_F(ControlTest, SupportsRequestUnreportedOptionsFail) { report_options_ = false; android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); // Unreported options should still be checked against. EXPECT_CALL(*mock_options_, IsSupported(test_option)).WillOnce(Return(false)); PrepareControl(); EXPECT_EQ(control_->SupportsRequestValues(metadata), false); } TEST_F(ControlTest, SupportsRequestInvalidNumber) { // Start with a request for multiple values. android::CameraMetadata metadata; std::vector<uint8_t> test_data = {1, 2, 3}; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_data), 0); PrepareControl(); EXPECT_EQ(control_->SupportsRequestValues(metadata), false); } TEST_F(ControlTest, SupportsRequestInvalidNumberNoOptions) { use_options_ = false; // Start with a request for multiple values. android::CameraMetadata metadata; std::vector<uint8_t> test_data = {1, 2, 3}; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_data), 0); PrepareControl(); // Not having any explicit options does not exempt a control // from requiring the right number of values. EXPECT_EQ(control_->SupportsRequestValues(metadata), false); } TEST_F(ControlTest, SupportsRequestEmpty) { android::CameraMetadata metadata; PrepareControl(); EXPECT_EQ(control_->SupportsRequestValues(metadata), true); } TEST_F(ControlTest, SetRequest) { android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); Expectation validation_check = EXPECT_CALL(*mock_options_, IsSupported(test_option)) .WillOnce(Return(true)); EXPECT_CALL(*mock_delegate_, SetValue(test_option)) .After(validation_check) .WillOnce(Return(0)); PrepareControl(); // Make the request. ASSERT_EQ(control_->SetRequestValues(metadata), 0); } TEST_F(ControlTest, SetRequestNoOptions) { use_options_ = false; android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); // No options, no validation check. EXPECT_CALL(*mock_delegate_, SetValue(test_option)).WillOnce(Return(0)); PrepareControl(); // Make the request. ASSERT_EQ(control_->SetRequestValues(metadata), 0); } TEST_F(ControlTest, SetRequestUnreportedOptions) { report_options_ = false; android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); // Unreported options still get a validation check. Expectation validation_check = EXPECT_CALL(*mock_options_, IsSupported(test_option)) .WillOnce(Return(true)); EXPECT_CALL(*mock_delegate_, SetValue(test_option)) .After(validation_check) .WillOnce(Return(0)); PrepareControl(); // Make the request. ASSERT_EQ(control_->SetRequestValues(metadata), 0); } TEST_F(ControlTest, SetRequestSettingFail) { android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); int err = 99; Expectation validation_check = EXPECT_CALL(*mock_options_, IsSupported(test_option)) .WillOnce(Return(true)); EXPECT_CALL(*mock_delegate_, SetValue(test_option)) .After(validation_check) .WillOnce(Return(err)); PrepareControl(); EXPECT_EQ(control_->SetRequestValues(metadata), err); } TEST_F(ControlTest, SetRequestValidationFail) { android::CameraMetadata metadata; uint8_t test_option = 123; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0); EXPECT_CALL(*mock_options_, IsSupported(test_option)).WillOnce(Return(false)); PrepareControl(); EXPECT_EQ(control_->SetRequestValues(metadata), -EINVAL); } TEST_F(ControlTest, SetRequestInvalidNumber) { // Start with a request for multiple values. android::CameraMetadata metadata; std::vector<uint8_t> test_data = {1, 2, 3}; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_data), 0); PrepareControl(); EXPECT_EQ(control_->SetRequestValues(metadata), -EINVAL); } TEST_F(ControlTest, SetRequestInvalidNumberNoOptions) { use_options_ = false; // Start with a request for multiple values. android::CameraMetadata metadata; std::vector<uint8_t> test_data = {1, 2, 3}; ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_data), 0); PrepareControl(); // Not having explicit options does not change that an incorrect // number of values is invalid. EXPECT_EQ(control_->SetRequestValues(metadata), -EINVAL); } TEST_F(ControlTest, SetRequestEmpty) { // Should do nothing. android::CameraMetadata metadata; PrepareControl(); EXPECT_EQ(control_->SetRequestValues(metadata), 0); } } // namespace v4l2_camera_hal