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 31namespace v4l2_camera_hal { 32 33enum 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. 38template <typename T> 39static 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. 43template <typename T> 44static 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. 48template <typename T> 49static 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. 56template <typename T> 57static 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. 66template <typename T> 67static 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. 75template <typename T> 76static 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|. 88template <typename T> 89static 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 101template <typename T> 102std::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 112template <typename T> 113std::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 124template <typename T> 125std::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 146template <typename T> 147std::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 163template <typename T> 164std::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 181template <typename T> 182std::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 307template <typename T> 308std::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