/* * 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_CONTROL_H_ #define V4L2_CAMERA_HAL_METADATA_CONTROL_H_ #include <vector> #include <system/camera_metadata.h> #include "../common.h" #include "metadata_common.h" #include "partial_metadata_interface.h" #include "tagged_control_delegate.h" #include "tagged_control_options.h" namespace v4l2_camera_hal { // A Control is a PartialMetadata with values that can be gotten/set. template <typename T> class Control : public PartialMetadataInterface { public: // Options are optional (i.e. nullable), delegate is not. Control(std::unique_ptr<TaggedControlDelegate<T>> delegate, std::unique_ptr<TaggedControlOptions<T>> options = nullptr); virtual std::vector<int32_t> StaticTags() const override; virtual std::vector<int32_t> ControlTags() const override; virtual std::vector<int32_t> DynamicTags() const override; virtual int PopulateStaticFields( android::CameraMetadata* metadata) const override; virtual int PopulateDynamicFields( android::CameraMetadata* metadata) const override; virtual int PopulateTemplateRequest( int template_type, android::CameraMetadata* metadata) const override; virtual bool SupportsRequestValues( const android::CameraMetadata& metadata) const override; virtual int SetRequestValues( const android::CameraMetadata& metadata) override; private: std::unique_ptr<TaggedControlDelegate<T>> delegate_; std::unique_ptr<TaggedControlOptions<T>> options_; DISALLOW_COPY_AND_ASSIGN(Control); }; // ----------------------------------------------------------------------------- template <typename T> Control<T>::Control(std::unique_ptr<TaggedControlDelegate<T>> delegate, std::unique_ptr<TaggedControlOptions<T>> options) : delegate_(std::move(delegate)), options_(std::move(options)) {} template <typename T> std::vector<int32_t> Control<T>::StaticTags() const { std::vector<int32_t> result; if (options_ && options_->tag() != DO_NOT_REPORT_OPTIONS) { result.push_back(options_->tag()); } return result; } template <typename T> std::vector<int32_t> Control<T>::ControlTags() const { return {delegate_->tag()}; } template <typename T> std::vector<int32_t> Control<T>::DynamicTags() const { return {delegate_->tag()}; } template <typename T> int Control<T>::PopulateStaticFields(android::CameraMetadata* metadata) const { if (!options_) { HAL_LOGV("No options for control %d, nothing to populate.", delegate_->tag()); return 0; } else if (options_->tag() == DO_NOT_REPORT_OPTIONS) { HAL_LOGV( "Options for control %d are not reported, " "probably are set values defined and already known by the API.", delegate_->tag()); return 0; } return UpdateMetadata( metadata, options_->tag(), options_->MetadataRepresentation()); } template <typename T> int Control<T>::PopulateDynamicFields(android::CameraMetadata* metadata) const { // Populate the current setting. T value; int res = delegate_->GetValue(&value); if (res) { return res; } return UpdateMetadata(metadata, delegate_->tag(), value); } template <typename T> int Control<T>::PopulateTemplateRequest( int template_type, android::CameraMetadata* metadata) const { // Populate with a default. T value; int res; if (options_) { res = options_->DefaultValueForTemplate(template_type, &value); } else { // If there's no options (and thus no default option), // fall back to whatever the current value is. res = delegate_->GetValue(&value); } if (res) { return res; } return UpdateMetadata(metadata, delegate_->tag(), value); } template <typename T> bool Control<T>::SupportsRequestValues( const android::CameraMetadata& metadata) const { if (metadata.isEmpty()) { // Implicitly supported. return true; } // Get the requested setting for this control. T requested; int res = SingleTagValue(metadata, delegate_->tag(), &requested); if (res == -ENOENT) { // Nothing requested of this control, that's fine. return true; } else if (res) { HAL_LOGE("Failure while searching for request value for tag %d", delegate_->tag()); return false; } // Check that the requested setting is in the supported options. if (!options_) { HAL_LOGV("No options for control %d; request implicitly supported.", delegate_->tag()); return true; } return options_->IsSupported(requested); } template <typename T> int Control<T>::SetRequestValues(const android::CameraMetadata& metadata) { if (metadata.isEmpty()) { // No changes necessary. return 0; } // Get the requested value. T requested; int res = SingleTagValue(metadata, delegate_->tag(), &requested); if (res == -ENOENT) { // Nothing requested of this control, nothing to do. return 0; } else if (res) { HAL_LOGE("Failure while searching for request value for tag %d", delegate_->tag()); return res; } // Check that the value is supported. if (options_ && !options_->IsSupported(requested)) { HAL_LOGE("Unsupported value requested for control %d.", delegate_->tag()); return -EINVAL; } return delegate_->SetValue(requested); } } // namespace v4l2_camera_hal #endif // V4L2_CAMERA_HAL_METADATA_CONTROL_H_