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