1 /*
2  * Copyright 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 #include "metadata.h"
18 
19 #include <camera/CameraMetadata.h>
20 #include <hardware/camera3.h>
21 
22 #include "../common.h"
23 #include "metadata_common.h"
24 
25 namespace v4l2_camera_hal {
26 
Metadata(PartialMetadataSet components)27 Metadata::Metadata(PartialMetadataSet components)
28     : components_(std::move(components)) {
29   HAL_LOG_ENTER();
30 }
31 
~Metadata()32 Metadata::~Metadata() {
33   HAL_LOG_ENTER();
34 }
35 
FillStaticMetadata(android::CameraMetadata * metadata)36 int Metadata::FillStaticMetadata(android::CameraMetadata* metadata) {
37   HAL_LOG_ENTER();
38   if (!metadata) {
39     HAL_LOGE("Can't fill null metadata.");
40     return -EINVAL;
41   }
42 
43   std::vector<int32_t> static_tags;
44   std::vector<int32_t> control_tags;
45   std::vector<int32_t> dynamic_tags;
46   int res = 0;
47 
48   for (auto& component : components_) {
49     // Prevent components from potentially overriding others.
50     android::CameraMetadata additional_metadata;
51     // Populate the fields.
52     res = component->PopulateStaticFields(&additional_metadata);
53     if (res) {
54       HAL_LOGE("Failed to get all static properties.");
55       return res;
56     }
57     // Add it to the overall result.
58     if (!additional_metadata.isEmpty()) {
59       res = metadata->append(additional_metadata);
60       if (res != android::OK) {
61         HAL_LOGE("Failed to append all static properties.");
62         return res;
63       }
64     }
65 
66     // Note what tags the component adds.
67     std::vector<int32_t> tags = component->StaticTags();
68     std::move(tags.begin(),
69               tags.end(),
70               std::inserter(static_tags, static_tags.end()));
71     tags = component->ControlTags();
72     std::move(tags.begin(),
73               tags.end(),
74               std::inserter(control_tags, control_tags.end()));
75     tags = component->DynamicTags();
76     std::move(tags.begin(),
77               tags.end(),
78               std::inserter(dynamic_tags, dynamic_tags.end()));
79   }
80 
81   // Populate the meta fields.
82   static_tags.push_back(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
83   res = UpdateMetadata(
84       metadata, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, control_tags);
85   if (res != android::OK) {
86     HAL_LOGE("Failed to add request keys meta key.");
87     return -ENODEV;
88   }
89   static_tags.push_back(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
90   res = UpdateMetadata(
91       metadata, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, dynamic_tags);
92   if (res != android::OK) {
93     HAL_LOGE("Failed to add result keys meta key.");
94     return -ENODEV;
95   }
96   static_tags.push_back(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
97   res = UpdateMetadata(
98       metadata, ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, static_tags);
99   if (res != android::OK) {
100     HAL_LOGE("Failed to add characteristics keys meta key.");
101     return -ENODEV;
102   }
103 
104   // TODO(b/31018853): cache result.
105   return 0;
106 }
107 
IsValidRequest(const android::CameraMetadata & metadata)108 bool Metadata::IsValidRequest(const android::CameraMetadata& metadata) {
109   HAL_LOG_ENTER();
110 
111   // Empty means "use previous settings", which are inherently valid.
112   if (metadata.isEmpty())
113     return true;
114 
115   for (auto& component : components_) {
116     // Check that all components support the values requested of them.
117     bool valid_request = component->SupportsRequestValues(metadata);
118     if (!valid_request) {
119       // Exit early if possible.
120       return false;
121     }
122   }
123 
124   return true;
125 }
126 
GetRequestTemplate(int template_type,android::CameraMetadata * template_metadata)127 int Metadata::GetRequestTemplate(int template_type,
128                                  android::CameraMetadata* template_metadata) {
129   HAL_LOG_ENTER();
130   if (!template_metadata) {
131     HAL_LOGE("Can't fill null template.");
132     return -EINVAL;
133   }
134 
135   // Templates are numbered 1 through COUNT-1 for some reason.
136   if (template_type < 1 || template_type >= CAMERA3_TEMPLATE_COUNT) {
137     HAL_LOGE("Unrecognized template type %d.", template_type);
138     return -EINVAL;
139   }
140 
141   for (auto& component : components_) {
142     // Prevent components from potentially overriding others.
143     android::CameraMetadata additional_metadata;
144     int res =
145         component->PopulateTemplateRequest(template_type, &additional_metadata);
146     if (res) {
147       HAL_LOGE("Failed to get all default request fields.");
148       return res;
149     }
150     // Add it to the overall result.
151     if (!additional_metadata.isEmpty()) {
152       res = template_metadata->append(additional_metadata);
153       if (res != android::OK) {
154         HAL_LOGE("Failed to append all default request fields.");
155         return res;
156       }
157     }
158   }
159 
160   // TODO(b/31018853): cache result.
161   return 0;
162 }
163 
SetRequestSettings(const android::CameraMetadata & metadata)164 int Metadata::SetRequestSettings(const android::CameraMetadata& metadata) {
165   HAL_LOG_ENTER();
166 
167   // Empty means "use previous settings".
168   if (metadata.isEmpty())
169     return 0;
170 
171   for (auto& component : components_) {
172     int res = component->SetRequestValues(metadata);
173     if (res) {
174       HAL_LOGE("Failed to set all requested settings.");
175       return res;
176     }
177   }
178 
179   return 0;
180 }
181 
FillResultMetadata(android::CameraMetadata * metadata)182 int Metadata::FillResultMetadata(android::CameraMetadata* metadata) {
183   HAL_LOG_ENTER();
184   if (!metadata) {
185     HAL_LOGE("Can't fill null metadata.");
186     return -EINVAL;
187   }
188 
189   for (auto& component : components_) {
190     // Prevent components from potentially overriding others.
191     android::CameraMetadata additional_metadata;
192     int res = component->PopulateDynamicFields(&additional_metadata);
193     if (res) {
194       HAL_LOGE("Failed to get all dynamic result fields.");
195       return res;
196     }
197     // Add it to the overall result.
198     if (!additional_metadata.isEmpty()) {
199       res = metadata->append(additional_metadata);
200       if (res != android::OK) {
201         HAL_LOGE("Failed to append all dynamic result fields.");
202         return res;
203       }
204     }
205   }
206 
207   return 0;
208 }
209 
210 }  // namespace v4l2_camera_hal
211