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_FACTORY_H_
18 #define V4L2_CAMERA_HAL_METADATA_CONTROL_FACTORY_H_
19
20 #include "common.h"
21 #include "control.h"
22 #include "menu_control_options.h"
23 #include "no_effect_control_delegate.h"
24 #include "ranged_converter.h"
25 #include "slider_control_options.h"
26 #include "state.h"
27 #include "tagged_control_delegate.h"
28 #include "tagged_control_options.h"
29 #include "v4l2_control_delegate.h"
30
31 namespace v4l2_camera_hal {
32
33 enum class ControlType { kMenu, kSlider };
34
35 // Static functions to create partial metadata. Nullptr is returned on failures.
36
37 // FixedState: A state that doesn't change.
38 template <typename T>
39 static std::unique_ptr<State<T>> FixedState(int32_t tag, T value);
40
41 // NoEffectOptionlessControl: A control that accepts any value,
42 // and has no effect. A default value is given.
43 template <typename T>
44 static std::unique_ptr<Control<T>> NoEffectOptionlessControl(
45 int32_t delegate_tag, T default_value);
46
47 // NoEffectMenuControl: Some menu options, but they have no effect.
48 template <typename T>
49 static std::unique_ptr<Control<T>> NoEffectMenuControl(
50 int32_t delegate_tag,
51 int32_t options_tag,
52 const std::vector<T>& options,
53 std::map<int, T> default_values = {});
54
55 // NoEffectSliderControl: A slider of options, but they have no effect.
56 template <typename T>
57 static std::unique_ptr<Control<T>> NoEffectSliderControl(
58 int32_t delegate_tag,
59 int32_t options_tag,
60 T min,
61 T max,
62 std::map<int, T> default_values = {});
63
64 // NoEffectControl: A control with no effect and only a single allowable
65 // value. Chooses an appropriate ControlOptionsInterface depending on type.
66 template <typename T>
67 static std::unique_ptr<Control<T>> NoEffectControl(
68 ControlType type,
69 int32_t delegate_tag,
70 int32_t options_tag,
71 T value,
72 std::map<int, T> default_values = {});
73
74 // V4L2Control: A control corresponding to a V4L2 control.
75 template <typename T>
76 static std::unique_ptr<Control<T>> V4L2Control(
77 ControlType type,
78 int32_t delegate_tag,
79 int32_t options_tag,
80 std::shared_ptr<V4L2Wrapper> device,
81 int control_id,
82 std::shared_ptr<ConverterInterface<T, int32_t>> converter,
83 std::map<int, T> default_values = {});
84
85 // V4L2ControlOrDefault: Like V4L2Control, but if the V4L2Control fails to
86 // initialize for some reason, this method will fall back to NoEffectControl
87 // with an initial value defined by |fallback_default|.
88 template <typename T>
89 static std::unique_ptr<Control<T>> V4L2ControlOrDefault(
90 ControlType type,
91 int32_t delegate_tag,
92 int32_t options_tag,
93 std::shared_ptr<V4L2Wrapper> device,
94 int control_id,
95 std::shared_ptr<ConverterInterface<T, int32_t>> converter,
96 T fallback_default,
97 std::map<int, T> default_values = {});
98
99 // -----------------------------------------------------------------------------
100
101 template <typename T>
FixedState(int32_t tag,T value)102 std::unique_ptr<State<T>> FixedState(int32_t tag, T value) {
103 HAL_LOG_ENTER();
104
105 // Take advantage of ControlDelegate inheriting from StateDelegate;
106 // This will only expose GetValue, not SetValue, so the default will
107 // always be returned.
108 return std::make_unique<State<T>>(
109 tag, std::make_unique<NoEffectControlDelegate<T>>(value));
110 }
111
112 template <typename T>
NoEffectOptionlessControl(int32_t delegate_tag,T default_value)113 std::unique_ptr<Control<T>> NoEffectOptionlessControl(int32_t delegate_tag,
114 T default_value) {
115 HAL_LOG_ENTER();
116
117 return std::make_unique<Control<T>>(
118 std::make_unique<TaggedControlDelegate<T>>(
119 delegate_tag,
120 std::make_unique<NoEffectControlDelegate<T>>(default_value)),
121 nullptr);
122 }
123
124 template <typename T>
NoEffectMenuControl(int32_t delegate_tag,int32_t options_tag,const std::vector<T> & options,std::map<int,T> default_values)125 std::unique_ptr<Control<T>> NoEffectMenuControl(
126 int32_t delegate_tag,
127 int32_t options_tag,
128 const std::vector<T>& options,
129 std::map<int, T> default_values) {
130 HAL_LOG_ENTER();
131
132 if (options.empty()) {
133 HAL_LOGE("At least one option must be provided.");
134 return nullptr;
135 }
136
137 return std::make_unique<Control<T>>(
138 std::make_unique<TaggedControlDelegate<T>>(
139 delegate_tag,
140 std::make_unique<NoEffectControlDelegate<T>>(options[0])),
141 std::make_unique<TaggedControlOptions<T>>(
142 options_tag,
143 std::make_unique<MenuControlOptions<T>>(options, default_values)));
144 }
145
146 template <typename T>
NoEffectSliderControl(int32_t delegate_tag,int32_t options_tag,T min,T max,std::map<int,T> default_values)147 std::unique_ptr<Control<T>> NoEffectSliderControl(
148 int32_t delegate_tag,
149 int32_t options_tag,
150 T min,
151 T max,
152 std::map<int, T> default_values) {
153 HAL_LOG_ENTER();
154
155 return std::make_unique<Control<T>>(
156 std::make_unique<TaggedControlDelegate<T>>(
157 delegate_tag, std::make_unique<NoEffectControlDelegate<T>>(min)),
158 std::make_unique<TaggedControlOptions<T>>(
159 options_tag,
160 std::make_unique<SliderControlOptions<T>>(min, max, default_values)));
161 }
162
163 template <typename T>
NoEffectControl(ControlType type,int32_t delegate_tag,int32_t options_tag,T value,std::map<int,T> default_values)164 std::unique_ptr<Control<T>> NoEffectControl(ControlType type,
165 int32_t delegate_tag,
166 int32_t options_tag,
167 T value,
168 std::map<int, T> default_values) {
169 HAL_LOG_ENTER();
170
171 switch (type) {
172 case ControlType::kMenu:
173 return NoEffectMenuControl<T>(
174 delegate_tag, options_tag, {value}, default_values);
175 case ControlType::kSlider:
176 return NoEffectSliderControl(
177 delegate_tag, options_tag, value, value, default_values);
178 }
179 }
180
181 template <typename T>
V4L2Control(ControlType type,int32_t delegate_tag,int32_t options_tag,std::shared_ptr<V4L2Wrapper> device,int control_id,std::shared_ptr<ConverterInterface<T,int32_t>> converter,std::map<int,T> default_values)182 std::unique_ptr<Control<T>> V4L2Control(
183 ControlType type,
184 int32_t delegate_tag,
185 int32_t options_tag,
186 std::shared_ptr<V4L2Wrapper> device,
187 int control_id,
188 std::shared_ptr<ConverterInterface<T, int32_t>> converter,
189 std::map<int, T> default_values) {
190 HAL_LOG_ENTER();
191
192 // Query the device.
193 v4l2_query_ext_ctrl control_query;
194 int res = device->QueryControl(control_id, &control_query);
195 if (res) {
196 HAL_LOGE("Failed to query control %d.", control_id);
197 return nullptr;
198 }
199
200 int32_t control_min = static_cast<int32_t>(control_query.minimum);
201 int32_t control_max = static_cast<int32_t>(control_query.maximum);
202 int32_t control_step = static_cast<int32_t>(control_query.step);
203 if (control_min > control_max) {
204 HAL_LOGE("No acceptable values (min %d is greater than max %d).",
205 control_min,
206 control_max);
207 return nullptr;
208 }
209
210 // Variables needed by the various switch statements.
211 std::vector<T> options;
212 T metadata_val;
213 T metadata_min;
214 T metadata_max;
215 // Set up the result converter and result options based on type.
216 std::shared_ptr<ConverterInterface<T, int32_t>> result_converter(converter);
217 std::unique_ptr<ControlOptionsInterface<T>> result_options;
218 switch (control_query.type) {
219 case V4L2_CTRL_TYPE_BOOLEAN:
220 if (type != ControlType::kMenu) {
221 HAL_LOGE(
222 "V4L2 control %d is of type %d, which isn't compatible with "
223 "desired metadata control type %d",
224 control_id,
225 control_query.type,
226 type);
227 return nullptr;
228 }
229
230 // Convert each available option,
231 // ignoring ones without a known conversion.
232 for (int32_t i = control_min; i <= control_max; i += control_step) {
233 res = converter->V4L2ToMetadata(i, &metadata_val);
234 if (res == -EINVAL) {
235 HAL_LOGV("V4L2 value %d for control %d has no metadata equivalent.",
236 i,
237 control_id);
238 continue;
239 } else if (res) {
240 HAL_LOGE("Error converting value %d for control %d.", i, control_id);
241 return nullptr;
242 }
243 options.push_back(metadata_val);
244 }
245 // Check to make sure there's at least one option.
246 if (options.empty()) {
247 HAL_LOGE("No valid options for control %d.", control_id);
248 return nullptr;
249 }
250
251 result_options.reset(new MenuControlOptions<T>(options, default_values));
252 // No converter changes necessary.
253 break;
254 case V4L2_CTRL_TYPE_INTEGER:
255 if (type != ControlType::kSlider) {
256 HAL_LOGE(
257 "V4L2 control %d is of type %d, which isn't compatible with "
258 "desired metadata control type %d",
259 control_id,
260 control_query.type,
261 type);
262 return nullptr;
263 }
264
265 // Upgrade to a range/step-clamping converter.
266 result_converter.reset(new RangedConverter<T, int32_t>(
267 converter, control_min, control_max, control_step));
268
269 // Convert the min and max.
270 res = result_converter->V4L2ToMetadata(control_min, &metadata_min);
271 if (res) {
272 HAL_LOGE(
273 "Failed to convert V4L2 min value %d for control %d to metadata.",
274 control_min,
275 control_id);
276 return nullptr;
277 }
278 res = result_converter->V4L2ToMetadata(control_max, &metadata_max);
279 if (res) {
280 HAL_LOGE(
281 "Failed to convert V4L2 max value %d for control %d to metadata.",
282 control_max,
283 control_id);
284 return nullptr;
285 }
286 result_options.reset(new SliderControlOptions<T>(
287 metadata_min, metadata_max, default_values));
288 break;
289 default:
290 HAL_LOGE("Control %d (%s) is of unsupported type %d",
291 control_id,
292 control_query.name,
293 control_query.type);
294 return nullptr;
295 }
296
297 // Construct the control.
298 return std::make_unique<Control<T>>(
299 std::make_unique<TaggedControlDelegate<T>>(
300 delegate_tag,
301 std::make_unique<V4L2ControlDelegate<T>>(
302 device, control_id, result_converter)),
303 std::make_unique<TaggedControlOptions<T>>(options_tag,
304 std::move(result_options)));
305 }
306
307 template <typename T>
V4L2ControlOrDefault(ControlType type,int32_t delegate_tag,int32_t options_tag,std::shared_ptr<V4L2Wrapper> device,int control_id,std::shared_ptr<ConverterInterface<T,int32_t>> converter,T fallback_default,std::map<int,T> default_values)308 std::unique_ptr<Control<T>> V4L2ControlOrDefault(
309 ControlType type,
310 int32_t delegate_tag,
311 int32_t options_tag,
312 std::shared_ptr<V4L2Wrapper> device,
313 int control_id,
314 std::shared_ptr<ConverterInterface<T, int32_t>> converter,
315 T fallback_default,
316 std::map<int, T> default_values) {
317 HAL_LOG_ENTER();
318
319 std::unique_ptr<Control<T>> result = V4L2Control(type,
320 delegate_tag,
321 options_tag,
322 device,
323 control_id,
324 converter,
325 default_values);
326 if (!result) {
327 result = NoEffectControl(
328 type, delegate_tag, options_tag, fallback_default, default_values);
329 }
330 return result;
331 }
332
333 } // namespace v4l2_camera_hal
334
335 #endif // V4L2_CAMERA_HAL_METADATA_CONTROL_FACTORY_H_
336