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