xref: /aosp_15_r20/hardware/interfaces/automotive/evs/aidl/impl/default/include/ConfigManager.h (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1 /*
2  * Copyright (C) 2023 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 #pragma once
18 
19 #include "ConfigManagerUtil.h"
20 
21 #include <aidl/android/hardware/automotive/evs/CameraParam.h>
22 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
23 #include <android-base/logging.h>
24 #include <system/camera_metadata.h>
25 
26 #include <tinyxml2.h>
27 
28 #include <limits>
29 #include <string>
30 #include <string_view>
31 #include <type_traits>
32 #include <unordered_map>
33 #include <unordered_set>
34 #include <vector>
35 
36 /*
37  * Please note that this is different from what is defined in
38  * libhardware/modules/camera/3_4/metadata/types.h; this has one additional
39  * field to store a framerate.
40  */
41 typedef struct {
42     int id;
43     int width;
44     int height;
45     ::aidl::android::hardware::graphics::common::PixelFormat format;
46     int type;
47     int framerate;
48 } StreamConfiguration;
49 
50 class ConfigManager final {
51   public:
52     static std::unique_ptr<ConfigManager> Create();
53     static std::unique_ptr<ConfigManager> Create(const std::string path);
54     ConfigManager(const ConfigManager&) = delete;
55     ConfigManager& operator=(const ConfigManager&) = delete;
56 
57     /* Camera device's capabilities and metadata */
58     class CameraInfo {
59       public:
60         enum class DeviceType : std::int32_t {
61             NONE = 0,
62             MOCK = 1,
63             V4L2 = 2,
64             VIDEO = 3,
65 
66             UNKNOWN = std::numeric_limits<std::underlying_type_t<DeviceType>>::max(),
67         };
68 
69         enum class PixelFormat : std::int32_t {
70             NV12 = 0,
71             NV21 = 1,
72             YV12 = 2,
73             I420 = 3,
74 
75             UNKNOWN = std::numeric_limits<std::underlying_type_t<DeviceType>>::max(),
76         };
77 
CameraInfo()78         CameraInfo() : characteristics(nullptr) {}
79 
80         virtual ~CameraInfo();
81 
82         /* Allocate memory for camera_metadata_t */
allocate(size_t entry_cap,size_t data_cap)83         bool allocate(size_t entry_cap, size_t data_cap) {
84             if (characteristics != nullptr) {
85                 LOG(ERROR) << "Camera metadata is already allocated";
86                 return false;
87             }
88 
89             characteristics = allocate_camera_metadata(entry_cap, data_cap);
90             return characteristics != nullptr;
91         }
92 
93         static DeviceType deviceTypeFromSV(const std::string_view sv);
94 
95         static PixelFormat pixelFormatFromSV(const std::string_view sv);
96 
97         DeviceType deviceType{DeviceType::NONE};
98 
99         /*
100          * List of supported controls that the primary client can program.
101          * Paraemters are stored with its valid range
102          */
103         std::unordered_map<::aidl::android::hardware::automotive::evs::CameraParam,
104                            std::tuple<int32_t, int32_t, int32_t>>
105                 controls;
106 
107         /*
108          * List of supported output stream configurations.
109          */
110         std::unordered_map<int32_t, StreamConfiguration> streamConfigurations;
111 
112         /*
113          * Internal storage for camera metadata.  Each entry holds a pointer to
114          * data and number of elements
115          */
116         std::unordered_map<camera_metadata_tag_t, std::pair<void*, size_t>> cameraMetadata;
117 
118         /* Camera module characteristics */
119         camera_metadata_t* characteristics;
120 
121         /* Format of media in a given media container. This field is effective
122          * only for DeviceType::VIDEO.
123          */
124         PixelFormat format;
125     };
126 
127     class CameraGroupInfo : public CameraInfo {
128       public:
CameraGroupInfo()129         CameraGroupInfo() {}
130 
131         /* ID of member camera devices */
132         std::unordered_set<std::string> devices;
133 
134         /* The capture operation of member camera devices are synchronized */
135         int32_t synchronized = 0;
136     };
137 
138     class SystemInfo {
139       public:
140         /* number of available cameras */
141         int32_t numCameras = 0;
142     };
143 
144     class DisplayInfo {
145       public:
146         /*
147          * List of supported input stream configurations.
148          */
149         std::unordered_map<int32_t, StreamConfiguration> streamConfigurations;
150     };
151 
152     /*
153      * Return system information
154      *
155      * @return SystemInfo
156      *         Constant reference of SystemInfo.
157      */
getSystemInfo()158     const SystemInfo& getSystemInfo() {
159         std::unique_lock<std::mutex> lock(mConfigLock);
160         mConfigCond.wait(lock, [this] { return mIsReady; });
161         return mSystemInfo;
162     }
163 
164     /*
165      * Return a list of camera identifiers
166      *
167      * This function assumes that it is not being called frequently.
168      *
169      * @return std::vector<std::string>
170      *         A vector that contains unique camera device identifiers.
171      */
getCameraIdList()172     std::vector<std::string> getCameraIdList() {
173         std::unique_lock<std::mutex> lock(mConfigLock);
174         mConfigCond.wait(lock, [this] { return mIsReady; });
175 
176         std::vector<std::string> aList;
177         aList.reserve(mCameraInfo.size());
178         for (auto&& v : mCameraInfo) {
179             aList.push_back(v.first);
180         }
181 
182         return aList;
183     }
184 
185     /*
186      * Return a list of camera group identifiers
187      *
188      * This function assumes that it is not being called frequently.
189      *
190      * @return std::vector<std::string>
191      *         A vector that contains unique camera device identifiers.
192      */
getCameraGroupIdList()193     std::vector<std::string> getCameraGroupIdList() {
194         std::unique_lock<std::mutex> lock(mConfigLock);
195         mConfigCond.wait(lock, [this] { return mIsReady; });
196 
197         std::vector<std::string> aList;
198         aList.reserve(mCameraGroups.size());
199         for (auto&& v : mCameraGroups) {
200             aList.push_back(v.first);
201         }
202 
203         return aList;
204     }
205 
206     /*
207      * Return a pointer to the camera group
208      *
209      * @return CameraGroup
210      *         A pointer to a camera group identified by a given id.
211      */
getCameraGroupInfo(const std::string & gid)212     std::unique_ptr<CameraGroupInfo>& getCameraGroupInfo(const std::string& gid) {
213         std::unique_lock<std::mutex> lock(mConfigLock);
214         mConfigCond.wait(lock, [this] { return mIsReady; });
215 
216         return mCameraGroups[gid];
217     }
218 
219     /*
220      * Return a camera metadata
221      *
222      * @param  cameraId
223      *         Unique camera node identifier in string
224      *
225      * @return unique_ptr<CameraInfo>
226      *         A pointer to CameraInfo that is associated with a given camera
227      *         ID.  This returns a null pointer if this does not recognize a
228      *         given camera identifier.
229      */
getCameraInfo(const std::string & cameraId)230     std::unique_ptr<CameraInfo>& getCameraInfo(const std::string& cameraId) noexcept {
231         std::unique_lock<std::mutex> lock(mConfigLock);
232         mConfigCond.wait(lock, [this] { return mIsReady; });
233 
234         return mCameraInfo[cameraId];
235     }
236 
237     /*
238      * Tell whether the configuration data is ready to be used
239      *
240      * @return bool
241      *         True if configuration data is ready to be consumed.
242      */
isReady()243     bool isReady() const { return mIsReady; }
244 
245   private:
246     /* Constructors */
ConfigManager()247     ConfigManager() : mBinaryFilePath("") {}
248 
249     static std::string_view sConfigDefaultPath;
250     static std::string_view sConfigOverridePath;
251 
252     /* System configuration */
253     SystemInfo mSystemInfo;
254 
255     /* Internal data structure for camera device information */
256     std::unordered_map<std::string, std::unique_ptr<CameraInfo>> mCameraInfo;
257 
258     /* Internal data structure for camera device information */
259     std::unordered_map<std::string, std::unique_ptr<DisplayInfo>> mDisplayInfo;
260 
261     /* Camera groups are stored in <groud id, CameraGroup> hash map */
262     std::unordered_map<std::string, std::unique_ptr<CameraGroupInfo>> mCameraGroups;
263 
264     /*
265      * Camera positions are stored in <position, camera id set> hash map.
266      * The position must be one of front, rear, left, and right.
267      */
268     std::unordered_map<std::string, std::unordered_set<std::string>> mCameraPosition;
269 
270     /* Configuration data lock */
271     mutable std::mutex mConfigLock;
272 
273     /*
274      * This condition is signalled when it completes a configuration data
275      * preparation.
276      */
277     std::condition_variable mConfigCond;
278 
279     /* A path to a binary configuration file */
280     const char* mBinaryFilePath;
281 
282     /* Configuration data readiness */
283     bool mIsReady = false;
284 
285     /*
286      * Parse a given EVS configuration file and store the information
287      * internally.
288      *
289      * @return bool
290      *         True if it completes parsing a file successfully.
291      */
292     bool readConfigDataFromXML(const std::string path) noexcept;
293 
294     /*
295      * read the information of the vehicle
296      *
297      * @param  aSysElem
298      *         A pointer to "system" XML element.
299      */
300     void readSystemInfo(const tinyxml2::XMLElement* const aSysElem);
301 
302     /*
303      * read the information of camera devices
304      *
305      * @param  aCameraElem
306      *         A pointer to "camera" XML element that may contain multiple
307      *         "device" elements.
308      */
309     void readCameraInfo(const tinyxml2::XMLElement* const aCameraElem);
310 
311     /*
312      * read display device information
313      *
314      * @param  aDisplayElem
315      *         A pointer to "display" XML element that may contain multiple
316      *         "device" elements.
317      */
318     void readDisplayInfo(const tinyxml2::XMLElement* const aDisplayElem);
319 
320     /*
321      * read camera device information
322      *
323      * @param  aCamera
324      *         A pointer to CameraInfo that will be completed by this
325      *         method.
326      *         aDeviceElem
327      *         A pointer to "device" XML element that contains camera module
328      *         capability info and its characteristics.
329      *
330      * @return bool
331      *         Return false upon any failure in reading and processing camera
332      *         device information.
333      */
334     bool readCameraDeviceInfo(CameraInfo* aCamera, const tinyxml2::XMLElement* aDeviceElem);
335 
336     /*
337      * read camera metadata
338      *
339      * @param  aCapElem
340      *         A pointer to "cap" XML element.
341      * @param  aCamera
342      *         A pointer to CameraInfo that is being filled by this method.
343      * @param  dataSize
344      *         Required size of memory to store camera metadata found in this
345      *         method.  This is calculated in this method and returned to the
346      *         caller for camera_metadata allocation.
347      *
348      * @return size_t
349      *         Number of camera metadata entries
350      */
351     size_t readCameraCapabilities(const tinyxml2::XMLElement* const aCapElem, CameraInfo* aCamera,
352                                   size_t& dataSize);
353 
354     /*
355      * read camera metadata
356      *
357      * @param  aParamElem
358      *         A pointer to "characteristics" XML element.
359      * @param  aCamera
360      *         A pointer to CameraInfo that is being filled by this method.
361      * @param  dataSize
362      *         Required size of memory to store camera metadata found in this
363      *         method.
364      *
365      * @return size_t
366      *         Number of camera metadata entries
367      */
368     size_t readCameraMetadata(const tinyxml2::XMLElement* const aParamElem, CameraInfo* aCamera,
369                               size_t& dataSize);
370 
371     /*
372      * construct camera_metadata_t from camera capabilities and metadata
373      *
374      * @param  aCamera
375      *         A pointer to CameraInfo that is being filled by this method.
376      * @param  totalEntries
377      *         Number of camera metadata entries to be added.
378      * @param  totalDataSize
379      *         Sum of sizes of camera metadata entries to be added.
380      *
381      * @return bool
382      *         False if either it fails to allocate memory for camera metadata
383      *         or its size is not large enough to add all found camera metadata
384      *         entries.
385      */
386     bool constructCameraMetadata(CameraInfo* aCamera, const size_t totalEntries,
387                                  const size_t totalDataSize);
388 
389     /*
390      * Read configuration data from the binary file
391      *
392      * @return bool
393      *         True if it succeeds to read configuration data from a binary
394      *         file.
395      */
396     bool readConfigDataFromBinary();
397 
398     /*
399      * Store configuration data to the file
400      *
401      * @return bool
402      *         True if it succeeds to serialize mCameraInfo to the file.
403      */
404     bool writeConfigDataToBinary();
405 
406     /*
407      * debugging method to print out all XML elements and their attributes in
408      * logcat message.
409      *
410      * @param  aNode
411      *         A pointer to the root XML element to navigate.
412      * @param  prefix
413      *         A prefix to XML string.
414      */
415     void printElementNames(const tinyxml2::XMLElement* aNode, const std::string& prefix = "") const;
416 };
417