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