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