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 #ifndef V4L2_CAMERA_HAL_METADATA_CONTROL_H_
18 #define V4L2_CAMERA_HAL_METADATA_CONTROL_H_
19 
20 #include <vector>
21 
22 #include <android-base/macros.h>
23 #include <system/camera_metadata.h>
24 #include "metadata_common.h"
25 #include "partial_metadata_interface.h"
26 #include "tagged_control_delegate.h"
27 #include "tagged_control_options.h"
28 
29 namespace v4l2_camera_hal {
30 
31 // A Control is a PartialMetadata with values that can be gotten/set.
32 template <typename T>
33 class Control : public PartialMetadataInterface {
34  public:
35   // Options are optional (i.e. nullable), delegate is not.
36   Control(std::unique_ptr<TaggedControlDelegate<T>> delegate,
37           std::unique_ptr<TaggedControlOptions<T>> options = nullptr);
38 
39   virtual std::vector<int32_t> StaticTags() const override;
40   virtual std::vector<int32_t> ControlTags() const override;
41   virtual std::vector<int32_t> DynamicTags() const override;
42 
43   virtual int PopulateStaticFields(
44       android::CameraMetadata* metadata) const override;
45   virtual int PopulateDynamicFields(
46       android::CameraMetadata* metadata) const override;
47   virtual int PopulateTemplateRequest(
48       int template_type, android::CameraMetadata* metadata) const override;
49   virtual bool SupportsRequestValues(
50       const android::CameraMetadata& metadata) const override;
51   virtual int SetRequestValues(
52       const android::CameraMetadata& metadata) override;
53 
54  private:
55   std::unique_ptr<TaggedControlDelegate<T>> delegate_;
56   std::unique_ptr<TaggedControlOptions<T>> options_;
57 
58   DISALLOW_COPY_AND_ASSIGN(Control);
59 };
60 
61 // -----------------------------------------------------------------------------
62 
63 template <typename T>
Control(std::unique_ptr<TaggedControlDelegate<T>> delegate,std::unique_ptr<TaggedControlOptions<T>> options)64 Control<T>::Control(std::unique_ptr<TaggedControlDelegate<T>> delegate,
65                     std::unique_ptr<TaggedControlOptions<T>> options)
66     : delegate_(std::move(delegate)), options_(std::move(options)) {}
67 
68 template <typename T>
StaticTags()69 std::vector<int32_t> Control<T>::StaticTags() const {
70   std::vector<int32_t> result;
71   if (options_ && options_->tag() != DO_NOT_REPORT_OPTIONS) {
72     result.push_back(options_->tag());
73   }
74   return result;
75 }
76 
77 template <typename T>
ControlTags()78 std::vector<int32_t> Control<T>::ControlTags() const {
79   return {delegate_->tag()};
80 }
81 
82 template <typename T>
DynamicTags()83 std::vector<int32_t> Control<T>::DynamicTags() const {
84   return {delegate_->tag()};
85 }
86 
87 template <typename T>
PopulateStaticFields(android::CameraMetadata * metadata)88 int Control<T>::PopulateStaticFields(android::CameraMetadata* metadata) const {
89   if (!options_) {
90     HAL_LOGV("No options for control %d, nothing to populate.",
91              delegate_->tag());
92     return 0;
93   } else if (options_->tag() == DO_NOT_REPORT_OPTIONS) {
94     HAL_LOGV(
95         "Options for control %d are not reported, "
96         "probably are set values defined and already known by the API.",
97         delegate_->tag());
98     return 0;
99   }
100 
101   return UpdateMetadata(
102       metadata, options_->tag(), options_->MetadataRepresentation());
103 }
104 
105 template <typename T>
PopulateDynamicFields(android::CameraMetadata * metadata)106 int Control<T>::PopulateDynamicFields(android::CameraMetadata* metadata) const {
107   // Populate the current setting.
108   T value;
109   int res = delegate_->GetValue(&value);
110   if (res) {
111     return res;
112   }
113   return UpdateMetadata(metadata, delegate_->tag(), value);
114 }
115 
116 template <typename T>
PopulateTemplateRequest(int template_type,android::CameraMetadata * metadata)117 int Control<T>::PopulateTemplateRequest(
118     int template_type, android::CameraMetadata* metadata) const {
119   // Populate with a default.
120   T value;
121   int res;
122   if (options_) {
123     res = options_->DefaultValueForTemplate(template_type, &value);
124   } else {
125     // If there's no options (and thus no default option),
126     // fall back to whatever the current value is.
127     res = delegate_->GetValue(&value);
128   }
129   if (res) {
130     return res;
131   }
132 
133   return UpdateMetadata(metadata, delegate_->tag(), value);
134 }
135 
136 template <typename T>
SupportsRequestValues(const android::CameraMetadata & metadata)137 bool Control<T>::SupportsRequestValues(
138     const android::CameraMetadata& metadata) const {
139   if (metadata.isEmpty()) {
140     // Implicitly supported.
141     return true;
142   }
143 
144   // Get the requested setting for this control.
145   T requested;
146   int res = SingleTagValue(metadata, delegate_->tag(), &requested);
147   if (res == -ENOENT) {
148     // Nothing requested of this control, that's fine.
149     return true;
150   } else if (res) {
151     HAL_LOGE("Failure while searching for request value for tag %d",
152              delegate_->tag());
153     return false;
154   }
155 
156   // Check that the requested setting is in the supported options.
157   if (!options_) {
158     HAL_LOGV("No options for control %d; request implicitly supported.",
159              delegate_->tag());
160     return true;
161   }
162   return options_->IsSupported(requested);
163 }
164 
165 template <typename T>
SetRequestValues(const android::CameraMetadata & metadata)166 int Control<T>::SetRequestValues(const android::CameraMetadata& metadata) {
167   if (metadata.isEmpty()) {
168     // No changes necessary.
169     return 0;
170   }
171 
172   // Get the requested value.
173   T requested;
174   int res = SingleTagValue(metadata, delegate_->tag(), &requested);
175   if (res == -ENOENT) {
176     // Nothing requested of this control, nothing to do.
177     return 0;
178   } else if (res) {
179     HAL_LOGE("Failure while searching for request value for tag %d",
180              delegate_->tag());
181     return res;
182   }
183 
184   // Check that the value is supported.
185   if (options_ && !options_->IsSupported(requested)) {
186     HAL_LOGE("Unsupported value requested for control %d.", delegate_->tag());
187     return -EINVAL;
188   }
189 
190   return delegate_->SetValue(requested);
191 }
192 
193 }  // namespace v4l2_camera_hal
194 
195 #endif  // V4L2_CAMERA_HAL_METADATA_CONTROL_H_
196