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