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