blob: db19b1dbb15138103701aed3a94ef105607211c9 [file] [log] [blame]
Ari Hausman-Cohen6c63b502016-08-02 11:28:29 -07001/*
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 "tagged_partial_metadata.h"
26
27namespace v4l2_camera_hal {
28
29// A Control is a PartialMetadata with values that can be gotten/set.
30template <typename T>
31class Control : public TaggedPartialMetadata {
32 public:
33 Control(int32_t control_tag, std::vector<int32_t> static_tags = {});
34
35 // Child classes still need to implement PopulateStaticFields.
36 virtual int PopulateDynamicFields(
37 android::CameraMetadata* metadata) const override;
38 virtual bool SupportsRequestValues(
39 const android::CameraMetadata& metadata) const override;
40 virtual int SetRequestValues(
41 const android::CameraMetadata& metadata) override;
42
43 protected:
44 // Simpler access to tag.
45 inline int32_t ControlTag() const { return ControlTags()[0]; }
46
47 // Get/Set the control value. Return non-0 on failure.
48 virtual int GetValue(T* value) const = 0;
49 virtual int SetValue(const T& value) = 0;
50 // Helper to check if val is supported by this control.
51 virtual bool IsSupported(const T& val) const = 0;
52
53 DISALLOW_COPY_AND_ASSIGN(Control);
54};
55
56// -----------------------------------------------------------------------------
57
58template <typename T>
59Control<T>::Control(int32_t control_tag, std::vector<int32_t> static_tags)
60 // Controls use the same tag for setting the control
61 // and getting the dynamic value.
62 : TaggedPartialMetadata(static_tags, {control_tag}, {control_tag}) {
63 HAL_LOG_ENTER();
64}
65
66template <typename T>
67int Control<T>::PopulateDynamicFields(android::CameraMetadata* metadata) const {
68 HAL_LOG_ENTER();
69
70 // Populate the current setting.
71 T value;
72 int res = GetValue(&value);
73 if (res) {
74 return res;
75 }
76 return UpdateMetadata(metadata, ControlTag(), value);
77}
78
79template <typename T>
80bool Control<T>::SupportsRequestValues(
81 const android::CameraMetadata& metadata) const {
82 HAL_LOG_ENTER();
83 if (metadata.isEmpty()) {
84 // Implicitly supported.
85 return true;
86 }
87
88 // Check that the requested setting is in the supported options.
89 T requested;
90 int res = SingleTagValue(metadata, ControlTag(), &requested);
91 if (res == -ENOENT) {
92 // Nothing requested of this control, that's fine.
93 return true;
94 } else if (res) {
95 HAL_LOGE("Failure while searching for request value for tag %d",
96 ControlTag());
97 return false;
98 }
99 return IsSupported(requested);
100}
101
102template <typename T>
103int Control<T>::SetRequestValues(const android::CameraMetadata& metadata) {
104 HAL_LOG_ENTER();
105 if (metadata.isEmpty()) {
106 // No changes necessary.
107 return 0;
108 }
109
110 // Get the requested value.
111 T requested;
112 int res = SingleTagValue(metadata, ControlTag(), &requested);
113 if (res == -ENOENT) {
114 // Nothing requested of this control, nothing to do.
115 return 0;
116 } else if (res) {
117 HAL_LOGE("Failure while searching for request value for tag %d",
118 ControlTag());
119 return res;
120 }
121
122 return SetValue(requested);
123}
124
125} // namespace v4l2_camera_hal
126
127#endif // V4L2_CAMERA_HAL_METADATA_CONTROL_H_