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