Revert "Add default implementation of AIDL EVS interface"
Revert submission 21585493-b218588089
Reason for revert: b/273324345
Reverted changes: /q/submissionid:21585493-b218588089
Change-Id: I2826a16105f8e7b03f852f9babffb03d78d53fd0
diff --git a/automotive/evs/aidl/impl/default/Android.bp b/automotive/evs/aidl/impl/default/Android.bp
index bf6c0be..dbe0314 100644
--- a/automotive/evs/aidl/impl/default/Android.bp
+++ b/automotive/evs/aidl/impl/default/Android.bp
@@ -24,56 +24,13 @@
cc_binary {
name: "android.hardware.automotive.evs-aidl-default-service",
defaults: ["EvsHalDefaults"],
- vintf_fragments: ["manifest_evs-default-service.xml"],
+ local_include_dirs: ["include"],
+ vintf_fragments: ["evs-default-service.xml"],
init_rc: ["evs-default-service.rc"],
vendor: true,
relative_install_path: "hw",
- cflags: [
- "-DGL_GLEXT_PROTOTYPES",
- "-DEGL_EGLEXT_PROTOTYPES",
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wthread-safety",
- ],
- srcs: [
- ":libgui_frame_event_aidl",
- "src/*.cpp"
- ],
+ srcs: ["src/*.cpp"],
shared_libs: [
- "android.hardware.graphics.bufferqueue@1.0",
- "android.hardware.graphics.bufferqueue@2.0",
- "android.hidl.token@1.0-utils",
- "libEGL",
- "libGLESv2",
- "libbase",
"libbinder_ndk",
- "libbufferqueueconverter",
- "libcamera_metadata",
- "libhardware_legacy",
- "libhidlbase",
- "liblog",
- "libnativewindow",
- "libtinyxml2",
- "libui",
- "libutils",
- "libyuv",
],
- static_libs: [
- "android.frameworks.automotive.display-V1-ndk",
- "android.hardware.automotive.evs-V1-ndk",
- "android.hardware.common-V2-ndk",
- "libaidlcommonsupport",
- "libcutils",
- ],
- local_include_dirs: ["include"],
- include_dirs: ["frameworks/native/include/"],
- required: ["evs_mock_hal_configuration.xml"],
-}
-
-prebuilt_etc {
- name: "evs_mock_hal_configuration.xml",
- soc_specific: true,
- src: "resources/evs_mock_configuration.xml",
- sub_dir: "automotive/evs",
}
diff --git a/automotive/evs/aidl/impl/default/evs-default-service.rc b/automotive/evs/aidl/impl/default/evs-default-service.rc
index 3da41ff..ea8e689 100644
--- a/automotive/evs/aidl/impl/default/evs-default-service.rc
+++ b/automotive/evs/aidl/impl/default/evs-default-service.rc
@@ -1,8 +1,5 @@
service vendor.evs-hal-default /vendor/bin/hw/android.hardware.automotive.evs-aidl-default-service
class early_hal
- priority -20
- user graphics
- group automotive_evs camera
- onrestart restart cardisplayproxyd
- onrestart restart evsmanagerd
+ user automotive_evs
+ group automotive_evs
disabled
diff --git a/automotive/evs/aidl/impl/default/evs-default-service.xml b/automotive/evs/aidl/impl/default/evs-default-service.xml
new file mode 100644
index 0000000..96ff9f6
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/evs-default-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.automotive.evs</name>
+ <transport>hwbinder</transport>
+ <version>1</version>
+ <interface>
+ <name>IEvsEnumerator</name>
+ <instance>hw/0</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/automotive/evs/aidl/impl/default/include/ConfigManager.h b/automotive/evs/aidl/impl/default/include/ConfigManager.h
deleted file mode 100644
index 1d5fe77..0000000
--- a/automotive/evs/aidl/impl/default/include/ConfigManager.h
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "ConfigManagerUtil.h"
-
-#include <aidl/android/hardware/automotive/evs/CameraParam.h>
-#include <aidl/android/hardware/graphics/common/PixelFormat.h>
-#include <android-base/logging.h>
-#include <system/camera_metadata.h>
-
-#include <tinyxml2.h>
-
-#include <string>
-#include <string_view>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-/*
- * Please note that this is different from what is defined in
- * libhardware/modules/camera/3_4/metadata/types.h; this has one additional
- * field to store a framerate.
- */
-typedef struct {
- int id;
- int width;
- int height;
- ::aidl::android::hardware::graphics::common::PixelFormat format;
- int type;
- int framerate;
-} StreamConfiguration;
-
-class ConfigManager final {
- public:
- static std::unique_ptr<ConfigManager> Create();
- ConfigManager(const ConfigManager&) = delete;
- ConfigManager& operator=(const ConfigManager&) = delete;
-
- /* Camera device's capabilities and metadata */
- class CameraInfo {
- public:
- CameraInfo() : characteristics(nullptr) {}
-
- virtual ~CameraInfo();
-
- /* Allocate memory for camera_metadata_t */
- bool allocate(size_t entry_cap, size_t data_cap) {
- if (characteristics != nullptr) {
- LOG(ERROR) << "Camera metadata is already allocated";
- return false;
- }
-
- characteristics = allocate_camera_metadata(entry_cap, data_cap);
- return characteristics != nullptr;
- }
-
- /*
- * List of supported controls that the primary client can program.
- * Paraemters are stored with its valid range
- */
- std::unordered_map<::aidl::android::hardware::automotive::evs::CameraParam,
- std::tuple<int32_t, int32_t, int32_t>>
- controls;
-
- /*
- * List of supported output stream configurations.
- */
- std::unordered_map<int32_t, StreamConfiguration> streamConfigurations;
-
- /*
- * Internal storage for camera metadata. Each entry holds a pointer to
- * data and number of elements
- */
- std::unordered_map<camera_metadata_tag_t, std::pair<void*, size_t>> cameraMetadata;
-
- /* Camera module characteristics */
- camera_metadata_t* characteristics;
- };
-
- class CameraGroupInfo : public CameraInfo {
- public:
- CameraGroupInfo() {}
-
- /* ID of member camera devices */
- std::unordered_set<std::string> devices;
-
- /* The capture operation of member camera devices are synchronized */
- int32_t synchronized = 0;
- };
-
- class SystemInfo {
- public:
- /* number of available cameras */
- int32_t numCameras = 0;
- };
-
- class DisplayInfo {
- public:
- /*
- * List of supported input stream configurations.
- */
- std::unordered_map<int32_t, StreamConfiguration> streamConfigurations;
- };
-
- /*
- * Return system information
- *
- * @return SystemInfo
- * Constant reference of SystemInfo.
- */
- const SystemInfo& getSystemInfo() {
- std::unique_lock<std::mutex> lock(mConfigLock);
- mConfigCond.wait(lock, [this] { return mIsReady; });
- return mSystemInfo;
- }
-
- /*
- * Return a list of camera identifiers
- *
- * This function assumes that it is not being called frequently.
- *
- * @return std::vector<std::string>
- * A vector that contains unique camera device identifiers.
- */
- std::vector<std::string> getCameraIdList() {
- std::unique_lock<std::mutex> lock(mConfigLock);
- mConfigCond.wait(lock, [this] { return mIsReady; });
-
- std::vector<std::string> aList;
- aList.reserve(mCameraInfo.size());
- for (auto&& v : mCameraInfo) {
- aList.push_back(v.first);
- }
-
- return aList;
- }
-
- /*
- * Return a list of camera group identifiers
- *
- * This function assumes that it is not being called frequently.
- *
- * @return std::vector<std::string>
- * A vector that contains unique camera device identifiers.
- */
- std::vector<std::string> getCameraGroupIdList() {
- std::unique_lock<std::mutex> lock(mConfigLock);
- mConfigCond.wait(lock, [this] { return mIsReady; });
-
- std::vector<std::string> aList;
- aList.reserve(mCameraGroups.size());
- for (auto&& v : mCameraGroups) {
- aList.push_back(v.first);
- }
-
- return aList;
- }
-
- /*
- * Return a pointer to the camera group
- *
- * @return CameraGroup
- * A pointer to a camera group identified by a given id.
- */
- std::unique_ptr<CameraGroupInfo>& getCameraGroupInfo(const std::string& gid) {
- std::unique_lock<std::mutex> lock(mConfigLock);
- mConfigCond.wait(lock, [this] { return mIsReady; });
-
- return mCameraGroups[gid];
- }
-
- /*
- * Return a camera metadata
- *
- * @param cameraId
- * Unique camera node identifier in string
- *
- * @return unique_ptr<CameraInfo>
- * A pointer to CameraInfo that is associated with a given camera
- * ID. This returns a null pointer if this does not recognize a
- * given camera identifier.
- */
- std::unique_ptr<CameraInfo>& getCameraInfo(const std::string& cameraId) noexcept {
- std::unique_lock<std::mutex> lock(mConfigLock);
- mConfigCond.wait(lock, [this] { return mIsReady; });
-
- return mCameraInfo[cameraId];
- }
-
- /*
- * Tell whether the configuration data is ready to be used
- *
- * @return bool
- * True if configuration data is ready to be consumed.
- */
- bool isReady() const { return mIsReady; }
-
- private:
- /* Constructors */
- ConfigManager() : mBinaryFilePath("") {}
-
- static std::string_view sConfigDefaultPath;
- static std::string_view sConfigOverridePath;
-
- /* System configuration */
- SystemInfo mSystemInfo;
-
- /* Internal data structure for camera device information */
- std::unordered_map<std::string, std::unique_ptr<CameraInfo>> mCameraInfo;
-
- /* Internal data structure for camera device information */
- std::unordered_map<std::string, std::unique_ptr<DisplayInfo>> mDisplayInfo;
-
- /* Camera groups are stored in <groud id, CameraGroup> hash map */
- std::unordered_map<std::string, std::unique_ptr<CameraGroupInfo>> mCameraGroups;
-
- /*
- * Camera positions are stored in <position, camera id set> hash map.
- * The position must be one of front, rear, left, and right.
- */
- std::unordered_map<std::string, std::unordered_set<std::string>> mCameraPosition;
-
- /* Configuration data lock */
- mutable std::mutex mConfigLock;
-
- /*
- * This condition is signalled when it completes a configuration data
- * preparation.
- */
- std::condition_variable mConfigCond;
-
- /* A path to a binary configuration file */
- const char* mBinaryFilePath;
-
- /* Configuration data readiness */
- bool mIsReady = false;
-
- /*
- * Parse a given EVS configuration file and store the information
- * internally.
- *
- * @return bool
- * True if it completes parsing a file successfully.
- */
- bool readConfigDataFromXML() noexcept;
-
- /*
- * read the information of the vehicle
- *
- * @param aSysElem
- * A pointer to "system" XML element.
- */
- void readSystemInfo(const tinyxml2::XMLElement* const aSysElem);
-
- /*
- * read the information of camera devices
- *
- * @param aCameraElem
- * A pointer to "camera" XML element that may contain multiple
- * "device" elements.
- */
- void readCameraInfo(const tinyxml2::XMLElement* const aCameraElem);
-
- /*
- * read display device information
- *
- * @param aDisplayElem
- * A pointer to "display" XML element that may contain multiple
- * "device" elements.
- */
- void readDisplayInfo(const tinyxml2::XMLElement* const aDisplayElem);
-
- /*
- * read camera device information
- *
- * @param aCamera
- * A pointer to CameraInfo that will be completed by this
- * method.
- * aDeviceElem
- * A pointer to "device" XML element that contains camera module
- * capability info and its characteristics.
- *
- * @return bool
- * Return false upon any failure in reading and processing camera
- * device information.
- */
- bool readCameraDeviceInfo(CameraInfo* aCamera, const tinyxml2::XMLElement* aDeviceElem);
-
- /*
- * read camera metadata
- *
- * @param aCapElem
- * A pointer to "cap" XML element.
- * @param aCamera
- * A pointer to CameraInfo that is being filled by this method.
- * @param dataSize
- * Required size of memory to store camera metadata found in this
- * method. This is calculated in this method and returned to the
- * caller for camera_metadata allocation.
- *
- * @return size_t
- * Number of camera metadata entries
- */
- size_t readCameraCapabilities(const tinyxml2::XMLElement* const aCapElem, CameraInfo* aCamera,
- size_t& dataSize);
-
- /*
- * read camera metadata
- *
- * @param aParamElem
- * A pointer to "characteristics" XML element.
- * @param aCamera
- * A pointer to CameraInfo that is being filled by this method.
- * @param dataSize
- * Required size of memory to store camera metadata found in this
- * method.
- *
- * @return size_t
- * Number of camera metadata entries
- */
- size_t readCameraMetadata(const tinyxml2::XMLElement* const aParamElem, CameraInfo* aCamera,
- size_t& dataSize);
-
- /*
- * construct camera_metadata_t from camera capabilities and metadata
- *
- * @param aCamera
- * A pointer to CameraInfo that is being filled by this method.
- * @param totalEntries
- * Number of camera metadata entries to be added.
- * @param totalDataSize
- * Sum of sizes of camera metadata entries to be added.
- *
- * @return bool
- * False if either it fails to allocate memory for camera metadata
- * or its size is not large enough to add all found camera metadata
- * entries.
- */
- bool constructCameraMetadata(CameraInfo* aCamera, const size_t totalEntries,
- const size_t totalDataSize);
-
- /*
- * Read configuration data from the binary file
- *
- * @return bool
- * True if it succeeds to read configuration data from a binary
- * file.
- */
- bool readConfigDataFromBinary();
-
- /*
- * Store configuration data to the file
- *
- * @return bool
- * True if it succeeds to serialize mCameraInfo to the file.
- */
- bool writeConfigDataToBinary();
-
- /*
- * debugging method to print out all XML elements and their attributes in
- * logcat message.
- *
- * @param aNode
- * A pointer to the root XML element to navigate.
- * @param prefix
- * A prefix to XML string.
- */
- void printElementNames(const tinyxml2::XMLElement* aNode, const std::string& prefix = "") const;
-};
diff --git a/automotive/evs/aidl/impl/default/include/ConfigManagerUtil.h b/automotive/evs/aidl/impl/default/include/ConfigManagerUtil.h
deleted file mode 100644
index 32b50d3..0000000
--- a/automotive/evs/aidl/impl/default/include/ConfigManagerUtil.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/hardware/automotive/evs/CameraParam.h>
-#include <aidl/android/hardware/graphics/common/PixelFormat.h>
-#include <android-base/macros.h>
-#include <system/camera_metadata.h>
-
-#include <string>
-#include <utility>
-
-class ConfigManagerUtil final {
- public:
- /**
- * Convert a given string into V4L2_CID_*
- */
- static bool convertToEvsCameraParam(
- const std::string& id,
- ::aidl::android::hardware::automotive::evs::CameraParam& camParam);
- /**
- * Convert a given string into android.hardware.graphics.common.PixelFormat
- */
- static bool convertToPixelFormat(const std::string& in,
- ::aidl::android::hardware::graphics::common::PixelFormat& out);
- /**
- * Convert a given string into corresponding camera metadata data tag defined in
- * system/media/camera/include/system/camera_metadata_tags.h
- */
- static bool convertToMetadataTag(const char* name, camera_metadata_tag& aTag);
- /**
- * Convert a given string into a floating value array
- */
- static float* convertFloatArray(const char* sz, const char* vals, size_t& count,
- const char delimiter = ',');
- /**
- * Trim a string
- */
- static std::string trimString(const std::string& src, const std::string& ws = " \n\r\t\f\v");
-
- /**
- * Convert a given string to corresponding camera capabilities
- */
- static bool convertToCameraCapability(
- const char* name, camera_metadata_enum_android_request_available_capabilities_t& cap);
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(ConfigManagerUtil);
-};
diff --git a/automotive/evs/aidl/impl/default/include/DefaultEvsEnumerator.h b/automotive/evs/aidl/impl/default/include/DefaultEvsEnumerator.h
new file mode 100644
index 0000000..03a578d
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/DefaultEvsEnumerator.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_evs_aidl_impl_evshal_include_DefaultEvsHal_H_
+#define android_hardware_automotive_evs_aidl_impl_evshal_include_DefaultEvsHal_H_
+
+#include <aidl/android/hardware/automotive/evs/BnEvsEnumerator.h>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+class DefaultEvsEnumerator final
+ : public ::aidl::android::hardware::automotive::evs::BnEvsEnumerator {
+ ::ndk::ScopedAStatus isHardware(bool* flag) override;
+ ::ndk::ScopedAStatus openCamera(
+ const std::string& cameraId,
+ const ::aidl::android::hardware::automotive::evs::Stream& streamConfig,
+ std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsCamera>* obj) override;
+ ::ndk::ScopedAStatus closeCamera(
+ const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsCamera>& obj)
+ override;
+ ::ndk::ScopedAStatus getCameraList(
+ std::vector<::aidl::android::hardware::automotive::evs::CameraDesc>* list) override;
+ ::ndk::ScopedAStatus getStreamList(
+ const ::aidl::android::hardware::automotive::evs::CameraDesc& desc,
+ std::vector<::aidl::android::hardware::automotive::evs::Stream>* _aidl_return) override;
+ ::ndk::ScopedAStatus openDisplay(
+ int32_t displayId,
+ std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsDisplay>* obj) override;
+ ::ndk::ScopedAStatus closeDisplay(
+ const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsDisplay>& obj)
+ override;
+ ::ndk::ScopedAStatus getDisplayIdList(std::vector<uint8_t>* list) override;
+ ::ndk::ScopedAStatus getDisplayState(
+ ::aidl::android::hardware::automotive::evs::DisplayState* state) override;
+ ::ndk::ScopedAStatus registerStatusCallback(
+ const std::shared_ptr<
+ ::aidl::android::hardware::automotive::evs::IEvsEnumeratorStatusCallback>&
+ callback) override;
+ ::ndk::ScopedAStatus openUltrasonicsArray(
+ const std::string& id,
+ std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsUltrasonicsArray>* obj)
+ override;
+ ::ndk::ScopedAStatus closeUltrasonicsArray(
+ const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsUltrasonicsArray>&
+ arr) override;
+ ::ndk::ScopedAStatus getUltrasonicsArrayList(
+ std::vector<::aidl::android::hardware::automotive::evs::UltrasonicsArrayDesc>* list)
+ override;
+};
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
+
+#endif // android_hardware_automotive_evs_aidl_impl_evshal_include_DefaultEvsHal_H_
diff --git a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
deleted file mode 100644
index b11dd3e..0000000
--- a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "ConfigManager.h"
-#include "EvsGlDisplay.h"
-#include "EvsMockCamera.h"
-
-#include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
-#include <aidl/android/hardware/automotive/evs/BnEvsEnumerator.h>
-#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
-#include <aidl/android/hardware/automotive/evs/DeviceStatusType.h>
-#include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
-#include <aidl/android/hardware/automotive/evs/IEvsEnumeratorStatusCallback.h>
-#include <aidl/android/hardware/automotive/evs/Stream.h>
-#include <utils/Thread.h>
-
-#include <atomic>
-#include <mutex>
-#include <optional>
-#include <thread>
-#include <unordered_map>
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-class EvsEnumerator final : public ::aidl::android::hardware::automotive::evs::BnEvsEnumerator {
- public:
- // Methods from ::aidl::android::hardware::automotive::evs::IEvsEnumerator
- ndk::ScopedAStatus isHardware(bool* flag) override;
- ndk::ScopedAStatus openCamera(const std::string& cameraId, const evs::Stream& streamConfig,
- std::shared_ptr<evs::IEvsCamera>* obj) override;
- ndk::ScopedAStatus closeCamera(const std::shared_ptr<evs::IEvsCamera>& obj) override;
- ndk::ScopedAStatus getCameraList(std::vector<evs::CameraDesc>* _aidl_return) override;
- ndk::ScopedAStatus getStreamList(const evs::CameraDesc& desc,
- std::vector<evs::Stream>* _aidl_return) override;
- ndk::ScopedAStatus openDisplay(int32_t displayId,
- std::shared_ptr<evs::IEvsDisplay>* obj) override;
- ndk::ScopedAStatus closeDisplay(const std::shared_ptr<evs::IEvsDisplay>& obj) override;
- ndk::ScopedAStatus getDisplayIdList(std::vector<uint8_t>* list) override;
- ndk::ScopedAStatus getDisplayState(evs::DisplayState* state) override;
- ndk::ScopedAStatus registerStatusCallback(
- const std::shared_ptr<evs::IEvsEnumeratorStatusCallback>& callback) override;
- ndk::ScopedAStatus openUltrasonicsArray(
- const std::string& id, std::shared_ptr<evs::IEvsUltrasonicsArray>* obj) override;
- ndk::ScopedAStatus closeUltrasonicsArray(
- const std::shared_ptr<evs::IEvsUltrasonicsArray>& obj) override;
- ndk::ScopedAStatus getUltrasonicsArrayList(
- std::vector<evs::UltrasonicsArrayDesc>* list) override;
-
- // Implementation details
- EvsEnumerator(const std::shared_ptr<
- ::aidl::android::frameworks::automotive::display::ICarDisplayProxy>&
- proxyService);
-
- void notifyDeviceStatusChange(const std::string_view& deviceName, evs::DeviceStatusType type);
-
- private:
- struct CameraRecord {
- evs::CameraDesc desc;
- std::weak_ptr<EvsMockCamera> activeInstance;
-
- CameraRecord(const char* cameraId) : desc() { desc.id = cameraId; }
- };
-
- class ActiveDisplays {
- public:
- struct DisplayInfo {
- int32_t id{-1};
- std::weak_ptr<EvsGlDisplay> displayWeak;
- uintptr_t internalDisplayRawAddr;
- };
-
- std::optional<DisplayInfo> popDisplay(int32_t id);
-
- std::optional<DisplayInfo> popDisplay(const std::shared_ptr<IEvsDisplay>& display);
-
- std::unordered_map<int32_t, DisplayInfo> getAllDisplays();
-
- bool tryInsert(int32_t id, const std::shared_ptr<EvsGlDisplay>& display);
-
- private:
- std::mutex mMutex;
- std::unordered_map<int32_t, DisplayInfo> mIdToDisplay GUARDED_BY(mMutex);
- std::unordered_map<uintptr_t, int32_t> mDisplayToId GUARDED_BY(mMutex);
- };
-
- bool checkPermission();
- void closeCamera_impl(const std::shared_ptr<evs::IEvsCamera>& pCamera,
- const std::string& cameraId);
-
- static bool qualifyCaptureDevice(const char* deviceName);
- static CameraRecord* findCameraById(const std::string& cameraId);
- static void enumerateCameras();
- static bool addCaptureDevice(const std::string& deviceName);
- static bool removeCaptureDevice(const std::string& deviceName);
- // Enumerate available displays and return an id of the internal display
- static uint64_t enumerateDisplays();
-
- static ActiveDisplays& mutableActiveDisplays();
-
- // NOTE: All members values are static so that all clients operate on the same state
- // That is to say, this is effectively a singleton despite the fact that HIDL
- // constructs a new instance for each client.
- // Because our server has a single thread in the thread pool, these values are
- // never accessed concurrently despite potentially having multiple instance objects
- // using them.
- static std::unordered_map<std::string, CameraRecord> sCameraList;
- // Object destructs if client dies.
- static std::mutex sLock; // Mutex on shared camera device list.
- static std::condition_variable sCameraSignal; // Signal on camera device addition.
- static std::unique_ptr<ConfigManager> sConfigManager; // ConfigManager
- static std::shared_ptr<::aidl::android::frameworks::automotive::display::ICarDisplayProxy>
- sDisplayProxy;
- static std::unordered_map<uint8_t, uint64_t> sDisplayPortList;
-
- uint64_t mInternalDisplayId;
- std::shared_ptr<evs::IEvsEnumeratorStatusCallback> mCallback;
-};
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h b/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h
deleted file mode 100644
index ceabd9e..0000000
--- a/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "GlWrapper.h"
-
-#include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
-#include <aidl/android/hardware/automotive/evs/BnEvsDisplay.h>
-#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
-#include <aidl/android/hardware/automotive/evs/DisplayDesc.h>
-#include <aidl/android/hardware/automotive/evs/DisplayState.h>
-
-#include <thread>
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-class EvsGlDisplay final : public BnEvsDisplay {
- public:
- // Methods from ::aidl::android::hardware::automotive::evs::IEvsDisplay
- // follow.
- ndk::ScopedAStatus getDisplayInfo(evs::DisplayDesc* _aidl_return) override;
- ndk::ScopedAStatus getDisplayState(evs::DisplayState* _aidl_return) override;
- ndk::ScopedAStatus getTargetBuffer(evs::BufferDesc* _aidl_return) override;
- ndk::ScopedAStatus returnTargetBufferForDisplay(const evs::BufferDesc& buffer) override;
- ndk::ScopedAStatus setDisplayState(evs::DisplayState state) override;
-
- // Implementation details
- EvsGlDisplay(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& service,
- uint64_t displayId);
- virtual ~EvsGlDisplay() override;
-
- // This gets called if another caller "steals" ownership of the display
- void forceShutdown();
-
- private:
- // A graphics buffer into which we'll store images. This member variable
- // will be protected by semaphores.
- struct BufferRecord {
- ::aidl::android::hardware::graphics::common::HardwareBufferDescription description;
- buffer_handle_t handle;
- int fingerprint;
- } mBuffer;
-
- // State of a rendering thread
- enum RenderThreadStates {
- STOPPED = 0,
- STOPPING = 1,
- RUN = 2,
- };
-
- uint64_t mDisplayId;
- evs::DisplayDesc mInfo;
- evs::DisplayState mRequestedState GUARDED_BY(mLock) = evs::DisplayState::NOT_VISIBLE;
- std::shared_ptr<automotivedisplay::ICarDisplayProxy> mDisplayProxy;
-
- GlWrapper mGlWrapper;
- mutable std::mutex mLock;
-
- // This tells us whether or not our buffer is in use. Protected by
- // semaphores.
- bool mBufferBusy = false;
-
- // Variables to synchronize a rendering thread w/ main and binder threads
- std::thread mRenderThread;
- RenderThreadStates mState GUARDED_BY(mLock) = STOPPED;
- bool mBufferReady = false;
- void renderFrames();
- bool initializeGlContextLocked() REQUIRES(mLock);
-
- std::condition_variable mBufferReadyToUse;
- std::condition_variable mBufferReadyToRender;
- std::condition_variable mBufferDone;
-};
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
deleted file mode 100644
index 46d47e7..0000000
--- a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "ConfigManager.h"
-
-#include <aidl/android/hardware/automotive/evs/BnEvsCamera.h>
-#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
-#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
-#include <aidl/android/hardware/automotive/evs/CameraParam.h>
-#include <aidl/android/hardware/automotive/evs/EvsResult.h>
-#include <aidl/android/hardware/automotive/evs/IEvsCameraStream.h>
-#include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
-#include <aidl/android/hardware/automotive/evs/ParameterRange.h>
-#include <aidl/android/hardware/automotive/evs/Stream.h>
-// #include <android-base/result.h>
-#include <android/hardware_buffer.h>
-#include <ui/GraphicBuffer.h>
-
-#include <functional>
-#include <thread>
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-class EvsMockCamera : public evs::BnEvsCamera {
- // This prevents constructors from direct access while it allows this class to
- // be instantiated via ndk::SharedRefBase::make<>.
- private:
- struct Sigil {
- explicit Sigil() = default;
- };
-
- public:
- // Methods from ::android::hardware::automotive::evs::IEvsCamera follow.
- ndk::ScopedAStatus doneWithFrame(const std::vector<evs::BufferDesc>& buffers) override;
- ndk::ScopedAStatus forcePrimaryClient(
- const std::shared_ptr<evs::IEvsDisplay>& display) override;
- ndk::ScopedAStatus getCameraInfo(evs::CameraDesc* _aidl_return) override;
- ndk::ScopedAStatus getExtendedInfo(int32_t opaqueIdentifier,
- std::vector<uint8_t>* value) override;
- ndk::ScopedAStatus getIntParameter(evs::CameraParam id, std::vector<int32_t>* value) override;
- ndk::ScopedAStatus getIntParameterRange(evs::CameraParam id,
- evs::ParameterRange* _aidl_return) override;
- ndk::ScopedAStatus getParameterList(std::vector<evs::CameraParam>* _aidl_return) override;
- ndk::ScopedAStatus getPhysicalCameraInfo(const std::string& deviceId,
- evs::CameraDesc* _aidl_return) override;
- ndk::ScopedAStatus importExternalBuffers(const std::vector<evs::BufferDesc>& buffers,
- int32_t* _aidl_return) override;
- ndk::ScopedAStatus pauseVideoStream() override;
- ndk::ScopedAStatus resumeVideoStream() override;
- ndk::ScopedAStatus setExtendedInfo(int32_t opaqueIdentifier,
- const std::vector<uint8_t>& opaqueValue) override;
- ndk::ScopedAStatus setIntParameter(evs::CameraParam id, int32_t value,
- std::vector<int32_t>* effectiveValue) override;
- ndk::ScopedAStatus setPrimaryClient() override;
- ndk::ScopedAStatus setMaxFramesInFlight(int32_t bufferCount) override;
- ndk::ScopedAStatus startVideoStream(
- const std::shared_ptr<evs::IEvsCameraStream>& receiver) override;
- ndk::ScopedAStatus stopVideoStream() override;
- ndk::ScopedAStatus unsetPrimaryClient() override;
-
- static std::shared_ptr<EvsMockCamera> Create(const char* deviceName);
- static std::shared_ptr<EvsMockCamera> Create(
- const char* deviceName, std::unique_ptr<ConfigManager::CameraInfo>& camInfo,
- const evs::Stream* streamCfg = nullptr);
- EvsMockCamera(const EvsMockCamera&) = delete;
- EvsMockCamera& operator=(const EvsMockCamera&) = delete;
-
- virtual ~EvsMockCamera() override;
- void shutdown();
-
- const evs::CameraDesc& getDesc() { return mDescription; }
-
- // Constructors
- EvsMockCamera(Sigil sigil, const char* deviceName,
- std::unique_ptr<ConfigManager::CameraInfo>& camInfo);
-
- private:
- // These three functions are expected to be called while mAccessLock is held
- bool setAvailableFrames_Locked(unsigned bufferCount);
- unsigned increaseAvailableFrames_Locked(unsigned numToAdd);
- unsigned decreaseAvailableFrames_Locked(unsigned numToRemove);
-
- void generateFrames();
- void fillMockFrame(buffer_handle_t handle, const AHardwareBuffer_Desc* pDesc);
- void returnBufferLocked(const uint32_t bufferId);
- ndk::ScopedAStatus stopVideoStream_impl();
-
- CameraDesc mDescription = {}; // The properties of this camera
-
- std::thread mCaptureThread; // The thread we'll use to synthesize frames
-
- // The callback used to deliver each frame
- std::shared_ptr<evs::IEvsCameraStream> mStream;
-
- // Horizontal pixel count in the buffers
- uint32_t mWidth = 0;
- // Vertical pixel count in the buffers
- uint32_t mHeight = 0;
- // Values from android_pixel_format_t
- uint32_t mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
- // Values from from Gralloc.h
- uint64_t mUsage =
- GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
- // Bytes per line in the buffers
- uint32_t mStride = 0;
-
- struct BufferRecord {
- buffer_handle_t handle;
- bool inUse;
-
- explicit BufferRecord(buffer_handle_t h) : handle(h), inUse(false){};
- };
-
- std::vector<BufferRecord> mBuffers; // Graphics buffers to transfer images
- unsigned mFramesAllowed; // How many buffers are we currently using
- unsigned mFramesInUse; // How many buffers are currently outstanding
-
- enum StreamStateValues {
- STOPPED,
- RUNNING,
- STOPPING,
- DEAD,
- };
- StreamStateValues mStreamState;
-
- // Synchronization necessary to deconflict mCaptureThread from the main service thread
- std::mutex mAccessLock;
-
- // Static camera module information
- std::unique_ptr<ConfigManager::CameraInfo>& mCameraInfo;
-
- // For the extended info
- std::unordered_map<uint32_t, std::vector<uint8_t>> mExtInfo;
- std::unordered_map<CameraParam, int32_t> mParams;
-};
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/GlWrapper.h b/automotive/evs/aidl/impl/default/include/GlWrapper.h
deleted file mode 100644
index adb250c..0000000
--- a/automotive/evs/aidl/impl/default/include/GlWrapper.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
-#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
-#include <android-base/logging.h>
-#include <bufferqueueconverter/BufferQueueConverter.h>
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-namespace automotivedisplay = ::aidl::android::frameworks::automotive::display;
-
-class GlWrapper {
- public:
- GlWrapper() : mSurfaceHolder(::android::SurfaceHolderUniquePtr(nullptr, nullptr)) {}
- bool initialize(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
- uint64_t displayId);
- void shutdown();
-
- bool updateImageTexture(
- buffer_handle_t handle,
- const ::aidl::android::hardware::graphics::common::HardwareBufferDescription&
- description);
- void renderImageToScreen();
-
- void showWindow(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
- uint64_t displayId);
- void hideWindow(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
- uint64_t displayId);
-
- unsigned getWidth() { return mWidth; };
- unsigned getHeight() { return mHeight; };
-
- private:
- ::android::sp<::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer>
- mGfxBufferProducer;
-
- EGLDisplay mDisplay;
- EGLSurface mSurface;
- EGLContext mContext;
-
- unsigned mWidth = 0;
- unsigned mHeight = 0;
-
- EGLImageKHR mKHRimage = EGL_NO_IMAGE_KHR;
-
- GLuint mTextureMap = 0;
- GLuint mShaderProgram = 0;
-
- // Opaque handle for a native hardware buffer defined in
- // frameworks/native/opengl/include/EGL/eglplatform.h
- ANativeWindow* mWindow;
-
- // Pointer to a Surface wrapper.
- ::android::SurfaceHolderUniquePtr mSurfaceHolder;
-};
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml b/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml
deleted file mode 100644
index 8480651..0000000
--- a/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<manifest version="1.0" type="device">
- <hal format="aidl">
- <name>android.hardware.automotive.evs</name>
- <fqname>IEvsEnumerator/hw/0</fqname>
- </hal>
-</manifest>
diff --git a/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml b/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml
deleted file mode 100644
index 6cbc18e..0000000
--- a/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- Exterior View System Example Configuration
-
- Android Automotive axes are used to define coordinates.
- See https://source.android.com/devices/sensors/sensor-types#auto_axes
-
- Use evs_configuration.dtd with xmllint tool, to validate XML configuration file
--->
-
-<configuration>
- <!-- system configuration -->
- <system>
- <!-- number of cameras available to EVS -->
- <num_cameras value='1'/>
- </system>
-
- <!-- camera information -->
- <camera>
- <!-- camera device starts -->
- <device id='/dev/video10' position='rear'>
- <caps>
- <!-- list of supported controls -->
- <supported_controls>
- <control name='BRIGHTNESS' min='0' max='255'/>
- <control name='CONTRAST' min='0' max='255'/>
- </supported_controls>
-
- <stream id='0' width='640' height='360' format='RGBA_8888' framerate='30'/>
- </caps>
-
- <!-- list of parameters -->
- <characteristics>
- <!-- Camera intrinsic calibration matrix. See
- https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#LENS_INTRINSIC_CALIBRATION
- -->
- <parameter
- name='LENS_INTRINSIC_CALIBRATION'
- type='float'
- size='5'
- value='0.0,0.0,0.0,0.0,0.0'
- />
- </characteristics>
- </device>
- </camera>
- <display>
- <device id='display0' position='driver'>
- <caps>
- <!-- list of supported inpu stream configurations -->
- <stream id='0' width='1280' height='720' format='RGBA_8888' framerate='30'/>
- </caps>
- </device>
- </display>
-</configuration>
-
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
deleted file mode 100644
index da791ed..0000000
--- a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
+++ /dev/null
@@ -1,992 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ConfigManager.h"
-
-#include <android-base/parseint.h>
-#include <hardware/gralloc.h>
-#include <utils/SystemClock.h>
-
-#include <fstream>
-#include <sstream>
-#include <string_view>
-#include <thread>
-
-namespace {
-
-using ::aidl::android::hardware::automotive::evs::CameraParam;
-using ::aidl::android::hardware::graphics::common::PixelFormat;
-using ::tinyxml2::XMLAttribute;
-using ::tinyxml2::XMLDocument;
-using ::tinyxml2::XMLElement;
-
-} // namespace
-
-std::string_view ConfigManager::sConfigDefaultPath =
- "/vendor/etc/automotive/evs/evs_mock_hal_configuration.xml";
-std::string_view ConfigManager::sConfigOverridePath =
- "/vendor/etc/automotive/evs/evs_configuration_override.xml";
-
-void ConfigManager::printElementNames(const XMLElement* rootElem, const std::string& prefix) const {
- const XMLElement* curElem = rootElem;
-
- while (curElem != nullptr) {
- LOG(VERBOSE) << "[ELEM] " << prefix << curElem->Name();
- const XMLAttribute* curAttr = curElem->FirstAttribute();
- while (curAttr) {
- LOG(VERBOSE) << "[ATTR] " << prefix << curAttr->Name() << ": " << curAttr->Value();
- curAttr = curAttr->Next();
- }
-
- /* recursively go down to descendants */
- printElementNames(curElem->FirstChildElement(), prefix + "\t");
-
- curElem = curElem->NextSiblingElement();
- }
-}
-
-void ConfigManager::readCameraInfo(const XMLElement* const aCameraElem) {
- if (aCameraElem == nullptr) {
- LOG(WARNING) << "XML file does not have required camera element";
- return;
- }
-
- const XMLElement* curElem = aCameraElem->FirstChildElement();
- while (curElem != nullptr) {
- if (!strcmp(curElem->Name(), "group")) {
- /* camera group identifier */
- const char* id = curElem->FindAttribute("id")->Value();
-
- /* create a camera group to be filled */
- CameraGroupInfo* aCamera = new CameraGroupInfo();
-
- /* read camera device information */
- if (!readCameraDeviceInfo(aCamera, curElem)) {
- LOG(WARNING) << "Failed to read a camera information of " << id;
- delete aCamera;
- continue;
- }
-
- /* camera group synchronization */
- const char* sync = curElem->FindAttribute("synchronized")->Value();
- if (!strcmp(sync, "CALIBRATED")) {
- aCamera->synchronized = ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED;
- } else if (!strcmp(sync, "APPROXIMATE")) {
- aCamera->synchronized = ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE;
- } else {
- aCamera->synchronized = 0; // Not synchronized
- }
-
- /* add a group to hash map */
- mCameraGroups.insert_or_assign(id, std::unique_ptr<CameraGroupInfo>(aCamera));
- } else if (!std::strcmp(curElem->Name(), "device")) {
- /* camera unique identifier */
- const char* id = curElem->FindAttribute("id")->Value();
-
- /* camera mount location */
- const char* pos = curElem->FindAttribute("position")->Value();
-
- /* create a camera device to be filled */
- CameraInfo* aCamera = new CameraInfo();
-
- /* read camera device information */
- if (!readCameraDeviceInfo(aCamera, curElem)) {
- LOG(WARNING) << "Failed to read a camera information of " << id;
- delete aCamera;
- continue;
- }
-
- /* store read camera module information */
- mCameraInfo.insert_or_assign(id, std::unique_ptr<CameraInfo>(aCamera));
-
- /* assign a camera device to a position group */
- mCameraPosition[pos].insert(id);
- } else {
- /* ignore other device types */
- LOG(DEBUG) << "Unknown element " << curElem->Name() << " is ignored";
- }
-
- curElem = curElem->NextSiblingElement();
- }
-}
-
-bool ConfigManager::readCameraDeviceInfo(CameraInfo* aCamera, const XMLElement* aDeviceElem) {
- if (aCamera == nullptr || aDeviceElem == nullptr) {
- return false;
- }
-
- /* size information to allocate camera_metadata_t */
- size_t totalEntries = 0;
- size_t totalDataSize = 0;
-
- /* read device capabilities */
- totalEntries +=
- readCameraCapabilities(aDeviceElem->FirstChildElement("caps"), aCamera, totalDataSize);
-
- /* read camera metadata */
- totalEntries += readCameraMetadata(aDeviceElem->FirstChildElement("characteristics"), aCamera,
- totalDataSize);
-
- /* construct camera_metadata_t */
- if (!constructCameraMetadata(aCamera, totalEntries, totalDataSize)) {
- LOG(WARNING) << "Either failed to allocate memory or "
- << "allocated memory was not large enough";
- }
-
- return true;
-}
-
-size_t ConfigManager::readCameraCapabilities(const XMLElement* const aCapElem, CameraInfo* aCamera,
- size_t& dataSize) {
- if (aCapElem == nullptr || aCamera == nullptr) {
- return 0;
- }
-
- std::string token;
- const XMLElement* curElem = nullptr;
-
- /* a list of supported camera parameters/controls */
- curElem = aCapElem->FirstChildElement("supported_controls");
- if (curElem != nullptr) {
- const XMLElement* ctrlElem = curElem->FirstChildElement("control");
- while (ctrlElem != nullptr) {
- const char* nameAttr = ctrlElem->FindAttribute("name")->Value();
- int32_t minVal = INT32_MIN, maxVal = INT32_MAX;
- if (!android::base::ParseInt(ctrlElem->FindAttribute("min")->Value(), &minVal)) {
- LOG(WARNING) << "Failed to parse " << ctrlElem->FindAttribute("min")->Value();
- }
-
- if (!android::base::ParseInt(ctrlElem->FindAttribute("max")->Value(), &maxVal)) {
- LOG(WARNING) << "Failed to parse " << ctrlElem->FindAttribute("max")->Value();
- }
-
- int32_t stepVal = 1;
- const XMLAttribute* stepAttr = ctrlElem->FindAttribute("step");
- if (stepAttr != nullptr) {
- if (!android::base::ParseInt(stepAttr->Value(), &stepVal)) {
- LOG(WARNING) << "Failed to parse " << stepAttr->Value();
- }
- }
-
- CameraParam aParam;
- if (ConfigManagerUtil::convertToEvsCameraParam(nameAttr, aParam)) {
- aCamera->controls.insert_or_assign(
- aParam, std::move(std::make_tuple(minVal, maxVal, stepVal)));
- }
-
- ctrlElem = ctrlElem->NextSiblingElement("control");
- }
- }
-
- /* a list of camera stream configurations */
- curElem = aCapElem->FirstChildElement("stream");
- while (curElem != nullptr) {
- /* read 5 attributes */
- const XMLAttribute* idAttr = curElem->FindAttribute("id");
- const XMLAttribute* widthAttr = curElem->FindAttribute("width");
- const XMLAttribute* heightAttr = curElem->FindAttribute("height");
- const XMLAttribute* fmtAttr = curElem->FindAttribute("format");
- const XMLAttribute* fpsAttr = curElem->FindAttribute("framerate");
-
- int32_t id = -1;
- int32_t framerate = 0;
- if (!android::base::ParseInt(idAttr->Value(), &id)) {
- LOG(WARNING) << "Failed to parse " << idAttr->Value();
- }
- if (fpsAttr != nullptr) {
- if (!android::base::ParseInt(fpsAttr->Value(), &framerate)) {
- LOG(WARNING) << "Failed to parse " << fpsAttr->Value();
- }
- }
-
- PixelFormat format = PixelFormat::UNSPECIFIED;
- if (ConfigManagerUtil::convertToPixelFormat(fmtAttr->Value(), format)) {
- StreamConfiguration cfg = {
- .id = id,
- .format = format,
- .type = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
- .framerate = framerate,
- };
-
- if (!android::base::ParseInt(widthAttr->Value(), &cfg.width) ||
- !android::base::ParseInt(heightAttr->Value(), &cfg.height)) {
- LOG(WARNING) << "Failed to parse " << widthAttr->Value() << " and "
- << heightAttr->Value();
- }
- aCamera->streamConfigurations.insert_or_assign(id, cfg);
- }
-
- curElem = curElem->NextSiblingElement("stream");
- }
-
- dataSize = calculate_camera_metadata_entry_data_size(
- get_camera_metadata_tag_type(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS),
- aCamera->streamConfigurations.size() * sizeof(StreamConfiguration));
-
- /* a single camera metadata entry contains multiple stream configurations */
- return dataSize > 0 ? 1 : 0;
-}
-
-size_t ConfigManager::readCameraMetadata(const XMLElement* const aParamElem, CameraInfo* aCamera,
- size_t& dataSize) {
- if (aParamElem == nullptr || aCamera == nullptr) {
- return 0;
- }
-
- const XMLElement* curElem = aParamElem->FirstChildElement("parameter");
- size_t numEntries = 0;
- camera_metadata_tag_t tag;
- while (curElem != nullptr) {
- if (ConfigManagerUtil::convertToMetadataTag(curElem->FindAttribute("name")->Value(), tag)) {
- switch (tag) {
- case ANDROID_LENS_DISTORTION:
- case ANDROID_LENS_POSE_ROTATION:
- case ANDROID_LENS_POSE_TRANSLATION:
- case ANDROID_LENS_INTRINSIC_CALIBRATION: {
- /* float[] */
- size_t count = 0;
- void* data = ConfigManagerUtil::convertFloatArray(
- curElem->FindAttribute("size")->Value(),
- curElem->FindAttribute("value")->Value(), count);
-
- aCamera->cameraMetadata.insert_or_assign(tag, std::make_pair(data, count));
-
- ++numEntries;
- dataSize += calculate_camera_metadata_entry_data_size(
- get_camera_metadata_tag_type(tag), count);
-
- break;
- }
-
- case ANDROID_REQUEST_AVAILABLE_CAPABILITIES: {
- camera_metadata_enum_android_request_available_capabilities_t* data =
- new camera_metadata_enum_android_request_available_capabilities_t[1];
- if (ConfigManagerUtil::convertToCameraCapability(
- curElem->FindAttribute("value")->Value(), *data)) {
- aCamera->cameraMetadata.insert_or_assign(tag,
- std::make_pair((void*)data, 1));
-
- ++numEntries;
- dataSize += calculate_camera_metadata_entry_data_size(
- get_camera_metadata_tag_type(tag), 1);
- }
- break;
- }
-
- case ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS: {
- /* a comma-separated list of physical camera devices */
- size_t len = strlen(curElem->FindAttribute("value")->Value());
- char* data = new char[len + 1];
- memcpy(data, curElem->FindAttribute("value")->Value(), len * sizeof(char));
-
- /* replace commas with null char */
- char* p = data;
- while (*p != '\0') {
- if (*p == ',') {
- *p = '\0';
- }
- ++p;
- }
-
- aCamera->cameraMetadata.insert_or_assign(tag,
- std::make_pair((void*)data, len + 1));
-
- ++numEntries;
- dataSize += calculate_camera_metadata_entry_data_size(
- get_camera_metadata_tag_type(tag), len);
- break;
- }
-
- /* TODO(b/140416878): add vendor-defined/custom tag support */
- default:
- LOG(WARNING) << "Parameter " << curElem->FindAttribute("name")->Value()
- << " is not supported";
- break;
- }
- } else {
- LOG(WARNING) << "Unsupported metadata tag " << curElem->FindAttribute("name")->Value()
- << " is found.";
- }
-
- curElem = curElem->NextSiblingElement("parameter");
- }
-
- return numEntries;
-}
-
-bool ConfigManager::constructCameraMetadata(CameraInfo* aCamera, size_t totalEntries,
- size_t totalDataSize) {
- if (aCamera == nullptr || !aCamera->allocate(totalEntries, totalDataSize)) {
- LOG(ERROR) << "Failed to allocate memory for camera metadata";
- return false;
- }
-
- const size_t numStreamConfigs = aCamera->streamConfigurations.size();
- std::unique_ptr<int32_t[]> data(new int32_t[sizeof(StreamConfiguration) * numStreamConfigs]);
- int32_t* ptr = data.get();
- for (auto& cfg : aCamera->streamConfigurations) {
- memcpy(ptr, &cfg.second, sizeof(StreamConfiguration));
- ptr += sizeof(StreamConfiguration);
- }
- int32_t err = add_camera_metadata_entry(
- aCamera->characteristics, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, data.get(),
- numStreamConfigs * sizeof(StreamConfiguration));
-
- if (err) {
- LOG(ERROR) << "Failed to add stream configurations to metadata, ignored";
- return false;
- }
-
- bool success = true;
- for (auto& [tag, entry] : aCamera->cameraMetadata) {
- /* try to add new camera metadata entry */
- int32_t err =
- add_camera_metadata_entry(aCamera->characteristics, tag, entry.first, entry.second);
- if (err) {
- LOG(ERROR) << "Failed to add an entry with a tag, " << std::hex << tag;
-
- /* may exceed preallocated capacity */
- LOG(ERROR) << "Camera metadata has "
- << get_camera_metadata_entry_count(aCamera->characteristics) << " / "
- << get_camera_metadata_entry_capacity(aCamera->characteristics)
- << " entries and "
- << get_camera_metadata_data_count(aCamera->characteristics) << " / "
- << get_camera_metadata_data_capacity(aCamera->characteristics)
- << " bytes are filled.";
- LOG(ERROR) << "\tCurrent metadata entry requires "
- << calculate_camera_metadata_entry_data_size(tag, entry.second) << " bytes.";
-
- success = false;
- }
- }
-
- LOG(VERBOSE) << "Camera metadata has "
- << get_camera_metadata_entry_count(aCamera->characteristics) << " / "
- << get_camera_metadata_entry_capacity(aCamera->characteristics) << " entries and "
- << get_camera_metadata_data_count(aCamera->characteristics) << " / "
- << get_camera_metadata_data_capacity(aCamera->characteristics)
- << " bytes are filled.";
- return success;
-}
-
-void ConfigManager::readSystemInfo(const XMLElement* const aSysElem) {
- if (aSysElem == nullptr) {
- return;
- }
-
- /*
- * Please note that this function assumes that a given system XML element
- * and its child elements follow DTD. If it does not, it will cause a
- * segmentation fault due to the failure of finding expected attributes.
- */
-
- /* read number of cameras available in the system */
- const XMLElement* xmlElem = aSysElem->FirstChildElement("num_cameras");
- if (xmlElem != nullptr) {
- if (!android::base::ParseInt(xmlElem->FindAttribute("value")->Value(),
- &mSystemInfo.numCameras)) {
- LOG(WARNING) << "Failed to parse " << xmlElem->FindAttribute("value")->Value();
- }
- }
-}
-
-void ConfigManager::readDisplayInfo(const XMLElement* const aDisplayElem) {
- if (aDisplayElem == nullptr) {
- LOG(WARNING) << "XML file does not have required camera element";
- return;
- }
-
- const XMLElement* curDev = aDisplayElem->FirstChildElement("device");
- while (curDev != nullptr) {
- const char* id = curDev->FindAttribute("id")->Value();
- std::unique_ptr<DisplayInfo> dpy(new DisplayInfo());
- if (dpy == nullptr) {
- LOG(ERROR) << "Failed to allocate memory for DisplayInfo";
- return;
- }
-
- const XMLElement* cap = curDev->FirstChildElement("caps");
- if (cap != nullptr) {
- const XMLElement* curStream = cap->FirstChildElement("stream");
- while (curStream != nullptr) {
- /* read 4 attributes */
- const XMLAttribute* idAttr = curStream->FindAttribute("id");
- const XMLAttribute* widthAttr = curStream->FindAttribute("width");
- const XMLAttribute* heightAttr = curStream->FindAttribute("height");
- const XMLAttribute* fmtAttr = curStream->FindAttribute("format");
-
- int32_t id = -1;
- if (!android::base::ParseInt(idAttr->Value(), &id)) {
- LOG(WARNING) << "Failed to parse " << idAttr->Value();
- }
- PixelFormat format = PixelFormat::UNSPECIFIED;
- if (ConfigManagerUtil::convertToPixelFormat(fmtAttr->Value(), format)) {
- StreamConfiguration cfg = {
- .id = id,
- .format = format,
- .type = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT,
- };
- if (!android::base::ParseInt(widthAttr->Value(), &cfg.width) ||
- !android::base::ParseInt(heightAttr->Value(), &cfg.height)) {
- LOG(WARNING) << "Failed to parse " << widthAttr->Value() << " and "
- << heightAttr->Value();
- }
- dpy->streamConfigurations.insert_or_assign(id, cfg);
- }
-
- curStream = curStream->NextSiblingElement("stream");
- }
- }
-
- mDisplayInfo.insert_or_assign(id, std::move(dpy));
- curDev = curDev->NextSiblingElement("device");
- }
-
- return;
-}
-
-bool ConfigManager::readConfigDataFromXML() noexcept {
- XMLDocument xmlDoc;
-
- const int64_t parsingStart = android::elapsedRealtimeNano();
-
- /* load and parse a configuration file */
- xmlDoc.LoadFile(sConfigOverridePath.data());
- if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
- xmlDoc.LoadFile(sConfigDefaultPath.data());
- if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
- LOG(ERROR) << "Failed to load and/or parse a configuration file, " << xmlDoc.ErrorStr();
- return false;
- }
- }
-
- /* retrieve the root element */
- const XMLElement* rootElem = xmlDoc.RootElement();
- if (std::strcmp(rootElem->Name(), "configuration") != 0) {
- LOG(ERROR) << "A configuration file is not in the required format. "
- << "See /etc/automotive/evs/evs_configuration.dtd";
- return false;
- }
-
- std::unique_lock<std::mutex> lock(mConfigLock);
-
- /*
- * parse camera information; this needs to be done before reading system
- * information
- */
- readCameraInfo(rootElem->FirstChildElement("camera"));
-
- /* parse system information */
- readSystemInfo(rootElem->FirstChildElement("system"));
-
- /* parse display information */
- readDisplayInfo(rootElem->FirstChildElement("display"));
-
- /* configuration data is ready to be consumed */
- mIsReady = true;
-
- /* notify that configuration data is ready */
- lock.unlock();
- mConfigCond.notify_all();
-
- const int64_t parsingEnd = android::elapsedRealtimeNano();
- LOG(INFO) << "Parsing configuration file takes " << std::scientific
- << (double)(parsingEnd - parsingStart) / 1000000.0 << " ms.";
-
- return true;
-}
-
-bool ConfigManager::readConfigDataFromBinary() {
- /* Temporary buffer to hold configuration data read from a binary file */
- char mBuffer[1024];
-
- std::fstream srcFile;
- const int64_t readStart = android::elapsedRealtimeNano();
-
- srcFile.open(mBinaryFilePath, std::fstream::in | std::fstream::binary);
- if (!srcFile) {
- LOG(ERROR) << "Failed to open a source binary file, " << mBinaryFilePath;
- return false;
- }
-
- std::unique_lock<std::mutex> lock(mConfigLock);
- mIsReady = false;
-
- /* read configuration data into the internal buffer */
- srcFile.read(mBuffer, sizeof(mBuffer));
- LOG(VERBOSE) << __FUNCTION__ << ": " << srcFile.gcount() << " bytes are read.";
- char* p = mBuffer;
- size_t sz = 0;
-
- /* read number of camera group information entries */
- const size_t ngrps = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
-
- /* read each camera information entry */
- for (size_t cidx = 0; cidx < ngrps; ++cidx) {
- /* read camera identifier */
- std::string cameraId = *(reinterpret_cast<std::string*>(p));
- p += sizeof(std::string);
-
- /* size of camera_metadata_t */
- const size_t num_entry = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
- const size_t num_data = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
-
- /* create CameraInfo and add it to hash map */
- std::unique_ptr<ConfigManager::CameraGroupInfo> aCamera;
- if (aCamera == nullptr || !aCamera->allocate(num_entry, num_data)) {
- LOG(ERROR) << "Failed to create new CameraInfo object";
- mCameraInfo.clear();
- return false;
- }
-
- /* controls */
- typedef struct {
- CameraParam cid;
- int32_t min;
- int32_t max;
- int32_t step;
- } CameraCtrl;
- sz = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
- CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
- for (size_t idx = 0; idx < sz; ++idx) {
- CameraCtrl temp = *ptr++;
- aCamera->controls.insert_or_assign(
- temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
- }
- p = reinterpret_cast<char*>(ptr);
-
- /* stream configurations */
- sz = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
- int32_t* i32_ptr = reinterpret_cast<int32_t*>(p);
- for (size_t idx = 0; idx < sz; ++idx) {
- const int32_t id = *i32_ptr++;
-
- StreamConfiguration temp;
- memcpy(&temp, i32_ptr, sizeof(StreamConfiguration));
- i32_ptr += sizeof(StreamConfiguration);
- aCamera->streamConfigurations.insert_or_assign(id, temp);
- }
- p = reinterpret_cast<char*>(i32_ptr);
-
- /* synchronization */
- aCamera->synchronized = *(reinterpret_cast<int32_t*>(p));
- p += sizeof(int32_t);
-
- for (size_t idx = 0; idx < num_entry; ++idx) {
- /* Read camera metadata entries */
- camera_metadata_tag_t tag = *reinterpret_cast<camera_metadata_tag_t*>(p);
- p += sizeof(camera_metadata_tag_t);
- const size_t count = *reinterpret_cast<size_t*>(p);
- p += sizeof(size_t);
-
- const int32_t type = get_camera_metadata_tag_type(tag);
- switch (type) {
- case TYPE_BYTE: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(uint8_t);
- break;
- }
- case TYPE_INT32: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(int32_t);
- break;
- }
- case TYPE_FLOAT: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(float);
- break;
- }
- case TYPE_INT64: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(int64_t);
- break;
- }
- case TYPE_DOUBLE: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(double);
- break;
- }
- case TYPE_RATIONAL:
- p += count * sizeof(camera_metadata_rational_t);
- break;
- default:
- LOG(WARNING) << "Type " << type << " is unknown; "
- << "data may be corrupted.";
- break;
- }
- }
-
- mCameraInfo.insert_or_assign(cameraId, std::move(aCamera));
- }
-
- /* read number of camera information entries */
- const size_t ncams = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
-
- /* read each camera information entry */
- for (size_t cidx = 0; cidx < ncams; ++cidx) {
- /* read camera identifier */
- std::string cameraId = *(reinterpret_cast<std::string*>(p));
- p += sizeof(std::string);
-
- /* size of camera_metadata_t */
- const size_t num_entry = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
- const size_t num_data = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
-
- /* create CameraInfo and add it to hash map */
- std::unique_ptr<ConfigManager::CameraInfo> aCamera;
- if (aCamera == nullptr || !aCamera->allocate(num_entry, num_data)) {
- LOG(ERROR) << "Failed to create new CameraInfo object";
- mCameraInfo.clear();
- return false;
- }
-
- /* controls */
- typedef struct {
- CameraParam cid;
- int32_t min;
- int32_t max;
- int32_t step;
- } CameraCtrl;
- sz = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
- CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
- for (size_t idx = 0; idx < sz; ++idx) {
- CameraCtrl temp = *ptr++;
- aCamera->controls.insert_or_assign(
- temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
- }
- p = reinterpret_cast<char*>(ptr);
-
- /* stream configurations */
- sz = *(reinterpret_cast<size_t*>(p));
- p += sizeof(size_t);
- int32_t* i32_ptr = reinterpret_cast<int32_t*>(p);
- for (size_t idx = 0; idx < sz; ++idx) {
- const int32_t id = *i32_ptr++;
-
- StreamConfiguration temp;
- memcpy(&temp, i32_ptr, sizeof(StreamConfiguration));
- i32_ptr += sizeof(StreamConfiguration);
- aCamera->streamConfigurations.insert_or_assign(id, temp);
- }
- p = reinterpret_cast<char*>(i32_ptr);
-
- for (size_t idx = 0; idx < num_entry; ++idx) {
- /* Read camera metadata entries */
- camera_metadata_tag_t tag = *reinterpret_cast<camera_metadata_tag_t*>(p);
- p += sizeof(camera_metadata_tag_t);
- const size_t count = *reinterpret_cast<size_t*>(p);
- p += sizeof(size_t);
-
- const int32_t type = get_camera_metadata_tag_type(tag);
- switch (type) {
- case TYPE_BYTE: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(uint8_t);
- break;
- }
- case TYPE_INT32: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(int32_t);
- break;
- }
- case TYPE_FLOAT: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(float);
- break;
- }
- case TYPE_INT64: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(int64_t);
- break;
- }
- case TYPE_DOUBLE: {
- add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
- p += count * sizeof(double);
- break;
- }
- case TYPE_RATIONAL:
- p += count * sizeof(camera_metadata_rational_t);
- break;
- default:
- LOG(WARNING) << "Type " << type << " is unknown; "
- << "data may be corrupted.";
- break;
- }
- }
-
- mCameraInfo.insert_or_assign(cameraId, std::move(aCamera));
- }
-
- mIsReady = true;
-
- /* notify that configuration data is ready */
- lock.unlock();
- mConfigCond.notify_all();
-
- int64_t readEnd = android::elapsedRealtimeNano();
- LOG(INFO) << __FUNCTION__ << " takes " << std::scientific
- << (double)(readEnd - readStart) / 1000000.0 << " ms.";
-
- return true;
-}
-
-bool ConfigManager::writeConfigDataToBinary() {
- std::fstream outFile;
-
- const int64_t writeStart = android::elapsedRealtimeNano();
-
- outFile.open(mBinaryFilePath, std::fstream::out | std::fstream::binary);
- if (!outFile) {
- LOG(ERROR) << "Failed to open a destination binary file, " << mBinaryFilePath;
- return false;
- }
-
- /* lock a configuration data while it's being written to the filesystem */
- std::lock_guard<std::mutex> lock(mConfigLock);
-
- /* write camera group information */
- size_t sz = mCameraGroups.size();
- outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
- for (auto&& [camId, camInfo] : mCameraGroups) {
- LOG(INFO) << "Storing camera group " << camId;
-
- /* write a camera identifier string */
- outFile.write(reinterpret_cast<const char*>(&camId), sizeof(std::string));
-
- /* controls */
- sz = camInfo->controls.size();
- outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
- for (auto&& [ctrl, range] : camInfo->controls) {
- outFile.write(reinterpret_cast<const char*>(&ctrl), sizeof(CameraParam));
- outFile.write(reinterpret_cast<const char*>(&std::get<0>(range)), sizeof(int32_t));
- outFile.write(reinterpret_cast<const char*>(&std::get<1>(range)), sizeof(int32_t));
- outFile.write(reinterpret_cast<const char*>(&std::get<2>(range)), sizeof(int32_t));
- }
-
- /* stream configurations */
- sz = camInfo->streamConfigurations.size();
- outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
- for (auto&& [sid, cfg] : camInfo->streamConfigurations) {
- outFile.write(reinterpret_cast<const char*>(sid), sizeof(int32_t));
- outFile.write(reinterpret_cast<const char*>(&cfg), sizeof(cfg));
- }
-
- /* synchronization */
- outFile.write(reinterpret_cast<const char*>(&camInfo->synchronized), sizeof(int32_t));
-
- /* size of camera_metadata_t */
- size_t num_entry = 0;
- size_t num_data = 0;
- if (camInfo->characteristics != nullptr) {
- num_entry = get_camera_metadata_entry_count(camInfo->characteristics);
- num_data = get_camera_metadata_data_count(camInfo->characteristics);
- }
- outFile.write(reinterpret_cast<const char*>(&num_entry), sizeof(size_t));
- outFile.write(reinterpret_cast<const char*>(&num_data), sizeof(size_t));
-
- /* write each camera metadata entry */
- if (num_entry > 0) {
- camera_metadata_entry_t entry;
- for (size_t idx = 0; idx < num_entry; ++idx) {
- if (get_camera_metadata_entry(camInfo->characteristics, idx, &entry)) {
- LOG(ERROR) << "Failed to retrieve camera metadata entry " << idx;
- outFile.close();
- return false;
- }
-
- outFile.write(reinterpret_cast<const char*>(&entry.tag), sizeof(entry.tag));
- outFile.write(reinterpret_cast<const char*>(&entry.count), sizeof(entry.count));
-
- int32_t type = get_camera_metadata_tag_type(entry.tag);
- switch (type) {
- case TYPE_BYTE:
- outFile.write(reinterpret_cast<const char*>(entry.data.u8),
- sizeof(uint8_t) * entry.count);
- break;
- case TYPE_INT32:
- outFile.write(reinterpret_cast<const char*>(entry.data.i32),
- sizeof(int32_t) * entry.count);
- break;
- case TYPE_FLOAT:
- outFile.write(reinterpret_cast<const char*>(entry.data.f),
- sizeof(float) * entry.count);
- break;
- case TYPE_INT64:
- outFile.write(reinterpret_cast<const char*>(entry.data.i64),
- sizeof(int64_t) * entry.count);
- break;
- case TYPE_DOUBLE:
- outFile.write(reinterpret_cast<const char*>(entry.data.d),
- sizeof(double) * entry.count);
- break;
- case TYPE_RATIONAL:
- [[fallthrough]];
- default:
- LOG(WARNING) << "Type " << type << " is not supported.";
- break;
- }
- }
- }
- }
-
- /* write camera device information */
- sz = mCameraInfo.size();
- outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
- for (auto&& [camId, camInfo] : mCameraInfo) {
- LOG(INFO) << "Storing camera " << camId;
-
- /* write a camera identifier string */
- outFile.write(reinterpret_cast<const char*>(&camId), sizeof(std::string));
-
- /* controls */
- sz = camInfo->controls.size();
- outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
- for (auto& [ctrl, range] : camInfo->controls) {
- outFile.write(reinterpret_cast<const char*>(&ctrl), sizeof(CameraParam));
- outFile.write(reinterpret_cast<const char*>(&std::get<0>(range)), sizeof(int32_t));
- outFile.write(reinterpret_cast<const char*>(&std::get<1>(range)), sizeof(int32_t));
- outFile.write(reinterpret_cast<const char*>(&std::get<2>(range)), sizeof(int32_t));
- }
-
- /* stream configurations */
- sz = camInfo->streamConfigurations.size();
- outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
- for (auto&& [sid, cfg] : camInfo->streamConfigurations) {
- outFile.write(reinterpret_cast<const char*>(sid), sizeof(int32_t));
- outFile.write(reinterpret_cast<const char*>(&cfg), sizeof(cfg));
- }
-
- /* size of camera_metadata_t */
- size_t num_entry = 0;
- size_t num_data = 0;
- if (camInfo->characteristics != nullptr) {
- num_entry = get_camera_metadata_entry_count(camInfo->characteristics);
- num_data = get_camera_metadata_data_count(camInfo->characteristics);
- }
- outFile.write(reinterpret_cast<const char*>(&num_entry), sizeof(size_t));
- outFile.write(reinterpret_cast<const char*>(&num_data), sizeof(size_t));
-
- /* write each camera metadata entry */
- if (num_entry > 0) {
- camera_metadata_entry_t entry;
- for (size_t idx = 0; idx < num_entry; ++idx) {
- if (get_camera_metadata_entry(camInfo->characteristics, idx, &entry)) {
- LOG(ERROR) << "Failed to retrieve camera metadata entry " << idx;
- outFile.close();
- return false;
- }
-
- outFile.write(reinterpret_cast<const char*>(&entry.tag), sizeof(entry.tag));
- outFile.write(reinterpret_cast<const char*>(&entry.count), sizeof(entry.count));
-
- int32_t type = get_camera_metadata_tag_type(entry.tag);
- switch (type) {
- case TYPE_BYTE:
- outFile.write(reinterpret_cast<const char*>(entry.data.u8),
- sizeof(uint8_t) * entry.count);
- break;
- case TYPE_INT32:
- outFile.write(reinterpret_cast<const char*>(entry.data.i32),
- sizeof(int32_t) * entry.count);
- break;
- case TYPE_FLOAT:
- outFile.write(reinterpret_cast<const char*>(entry.data.f),
- sizeof(float) * entry.count);
- break;
- case TYPE_INT64:
- outFile.write(reinterpret_cast<const char*>(entry.data.i64),
- sizeof(int64_t) * entry.count);
- break;
- case TYPE_DOUBLE:
- outFile.write(reinterpret_cast<const char*>(entry.data.d),
- sizeof(double) * entry.count);
- break;
- case TYPE_RATIONAL:
- [[fallthrough]];
- default:
- LOG(WARNING) << "Type " << type << " is not supported.";
- break;
- }
- }
- }
- }
-
- outFile.close();
- int64_t writeEnd = android::elapsedRealtimeNano();
- LOG(INFO) << __FUNCTION__ << " takes " << std::scientific
- << (double)(writeEnd - writeStart) / 1000000.0 << " ms.";
-
- return true;
-}
-
-std::unique_ptr<ConfigManager> ConfigManager::Create() {
- std::unique_ptr<ConfigManager> cfgMgr(new ConfigManager());
-
- /*
- * Read a configuration from XML file
- *
- * If this is too slow, ConfigManager::readConfigDataFromBinary() and
- * ConfigManager::writeConfigDataToBinary()can serialize CameraInfo object
- * to the filesystem and construct CameraInfo instead; this was
- * evaluated as 10x faster.
- */
- if (!cfgMgr->readConfigDataFromXML()) {
- return nullptr;
- } else {
- return cfgMgr;
- }
-}
-
-ConfigManager::CameraInfo::~CameraInfo() {
- free_camera_metadata(characteristics);
-
- for (auto&& [tag, val] : cameraMetadata) {
- switch (tag) {
- case ANDROID_LENS_DISTORTION:
- case ANDROID_LENS_POSE_ROTATION:
- case ANDROID_LENS_POSE_TRANSLATION:
- case ANDROID_LENS_INTRINSIC_CALIBRATION: {
- delete[] reinterpret_cast<float*>(val.first);
- break;
- }
-
- case ANDROID_REQUEST_AVAILABLE_CAPABILITIES: {
- delete[] reinterpret_cast<
- camera_metadata_enum_android_request_available_capabilities_t*>(val.first);
- break;
- }
-
- case ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS: {
- delete[] reinterpret_cast<char*>(val.first);
- break;
- }
-
- default:
- LOG(WARNING) << "Tag " << std::hex << tag << " is not supported. "
- << "Data may be corrupted?";
- break;
- }
- }
-}
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManagerUtil.cpp b/automotive/evs/aidl/impl/default/src/ConfigManagerUtil.cpp
deleted file mode 100644
index e5fe6ef..0000000
--- a/automotive/evs/aidl/impl/default/src/ConfigManagerUtil.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ConfigManagerUtil.h"
-
-#include <android-base/logging.h>
-#include <android-base/parsedouble.h>
-#include <android-base/parseint.h>
-#include <linux/videodev2.h>
-
-#include <sstream>
-#include <string>
-
-#include <system/graphics-base-v1.0.h>
-
-using ::aidl::android::hardware::automotive::evs::CameraParam;
-using ::aidl::android::hardware::graphics::common::PixelFormat;
-
-bool ConfigManagerUtil::convertToEvsCameraParam(const std::string& id, CameraParam& camParam) {
- std::string trimmed = ConfigManagerUtil::trimString(id);
- bool success = true;
-
- if (!trimmed.compare("BRIGHTNESS")) {
- camParam = CameraParam::BRIGHTNESS;
- } else if (!trimmed.compare("CONTRAST")) {
- camParam = CameraParam::CONTRAST;
- } else if (!trimmed.compare("AUTOGAIN")) {
- camParam = CameraParam::AUTOGAIN;
- } else if (!trimmed.compare("GAIN")) {
- camParam = CameraParam::GAIN;
- } else if (!trimmed.compare("AUTO_WHITE_BALANCE")) {
- camParam = CameraParam::AUTO_WHITE_BALANCE;
- } else if (!trimmed.compare("WHITE_BALANCE_TEMPERATURE")) {
- camParam = CameraParam::WHITE_BALANCE_TEMPERATURE;
- } else if (!trimmed.compare("SHARPNESS")) {
- camParam = CameraParam::SHARPNESS;
- } else if (!trimmed.compare("AUTO_EXPOSURE")) {
- camParam = CameraParam::AUTO_EXPOSURE;
- } else if (!trimmed.compare("ABSOLUTE_EXPOSURE")) {
- camParam = CameraParam::ABSOLUTE_EXPOSURE;
- } else if (!trimmed.compare("ABSOLUTE_FOCUS")) {
- camParam = CameraParam::ABSOLUTE_FOCUS;
- } else if (!trimmed.compare("AUTO_FOCUS")) {
- camParam = CameraParam::AUTO_FOCUS;
- } else if (!trimmed.compare("ABSOLUTE_ZOOM")) {
- camParam = CameraParam::ABSOLUTE_ZOOM;
- } else {
- success = false;
- }
-
- return success;
-}
-
-bool ConfigManagerUtil::convertToPixelFormat(const std::string& in, PixelFormat& out) {
- std::string trimmed = ConfigManagerUtil::trimString(in);
- bool success = true;
-
- if (!trimmed.compare("RGBA_8888")) {
- out = PixelFormat::RGBA_8888;
- } else if (!trimmed.compare("YCRCB_420_SP")) {
- out = PixelFormat::YCRCB_420_SP;
- } else if (!trimmed.compare("YCBCR_422_I")) {
- out = PixelFormat::YCBCR_422_I;
- } else {
- out = PixelFormat::UNSPECIFIED;
- success = false;
- }
-
- return success;
-}
-
-bool ConfigManagerUtil::convertToMetadataTag(const char* name, camera_metadata_tag& aTag) {
- if (!std::strcmp(name, "LENS_DISTORTION")) {
- aTag = ANDROID_LENS_DISTORTION;
- } else if (!std::strcmp(name, "LENS_INTRINSIC_CALIBRATION")) {
- aTag = ANDROID_LENS_INTRINSIC_CALIBRATION;
- } else if (!std::strcmp(name, "LENS_POSE_ROTATION")) {
- aTag = ANDROID_LENS_POSE_ROTATION;
- } else if (!std::strcmp(name, "LENS_POSE_TRANSLATION")) {
- aTag = ANDROID_LENS_POSE_TRANSLATION;
- } else if (!std::strcmp(name, "REQUEST_AVAILABLE_CAPABILITIES")) {
- aTag = ANDROID_REQUEST_AVAILABLE_CAPABILITIES;
- } else if (!std::strcmp(name, "LOGICAL_MULTI_CAMERA_PHYSICAL_IDS")) {
- aTag = ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS;
- } else {
- return false;
- }
-
- return true;
-}
-
-bool ConfigManagerUtil::convertToCameraCapability(
- const char* name, camera_metadata_enum_android_request_available_capabilities_t& cap) {
- if (!std::strcmp(name, "DEPTH_OUTPUT")) {
- cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT;
- } else if (!std::strcmp(name, "LOGICAL_MULTI_CAMERA")) {
- cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA;
- } else if (!std::strcmp(name, "MONOCHROME")) {
- cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME;
- } else if (!std::strcmp(name, "SECURE_IMAGE_DATA")) {
- cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA;
- } else {
- return false;
- }
-
- return true;
-}
-
-float* ConfigManagerUtil::convertFloatArray(const char* sz, const char* vals, size_t& count,
- const char delimiter) {
- std::string size_string(sz);
- std::string value_string(vals);
-
- if (!android::base::ParseUint(size_string, &count)) {
- LOG(ERROR) << "Failed to parse " << size_string;
- return nullptr;
- }
- float* result = new float[count];
- std::stringstream values(value_string);
-
- int32_t idx = 0;
- std::string token;
- while (getline(values, token, delimiter)) {
- if (!android::base::ParseFloat(token, &result[idx++])) {
- LOG(WARNING) << "Failed to parse " << token;
- }
- }
-
- return result;
-}
-
-std::string ConfigManagerUtil::trimString(const std::string& src, const std::string& ws) {
- const auto s = src.find_first_not_of(ws);
- if (s == std::string::npos) {
- return "";
- }
-
- const auto e = src.find_last_not_of(ws);
- const auto r = e - s + 1;
-
- return src.substr(s, r);
-}
diff --git a/automotive/evs/aidl/impl/default/src/DefaultEvsEnumerator.cpp b/automotive/evs/aidl/impl/default/src/DefaultEvsEnumerator.cpp
new file mode 100644
index 0000000..5a81d05
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/DefaultEvsEnumerator.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// TODO(b/203661081): Remove below lines to disable compiler warnings.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+
+#define LOG_TAG "DefaultEvsEnumerator"
+
+#include <DefaultEvsEnumerator.h>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+using ::ndk::ScopedAStatus;
+
+ScopedAStatus DefaultEvsEnumerator::isHardware(bool* flag) {
+ // This returns true always.
+ *flag = true;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::openCamera(const std::string& cameraId,
+ const Stream& streamConfig,
+ std::shared_ptr<IEvsCamera>* obj) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::closeCamera(const std::shared_ptr<IEvsCamera>& obj) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::getCameraList(std::vector<CameraDesc>* list) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::getStreamList(const CameraDesc& desc,
+ std::vector<Stream>* _aidl_return) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::openDisplay(int32_t displayId,
+ std::shared_ptr<IEvsDisplay>* obj) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::closeDisplay(const std::shared_ptr<IEvsDisplay>& state) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::getDisplayIdList(std::vector<uint8_t>* list) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::getDisplayState(DisplayState* state) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::registerStatusCallback(
+ const std::shared_ptr<IEvsEnumeratorStatusCallback>& callback) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::openUltrasonicsArray(
+ const std::string& id, std::shared_ptr<IEvsUltrasonicsArray>* obj) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::closeUltrasonicsArray(
+ const std::shared_ptr<IEvsUltrasonicsArray>& obj) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultEvsEnumerator::getUltrasonicsArrayList(
+ std::vector<UltrasonicsArrayDesc>* list) {
+ return ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
+
+#pragma clang diagnostic pop
diff --git a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
deleted file mode 100644
index 6e2405d..0000000
--- a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "EvsEnumerator.h"
-
-#include "ConfigManager.h"
-#include "EvsGlDisplay.h"
-#include "EvsMockCamera.h"
-
-#include <aidl/android/hardware/automotive/evs/EvsResult.h>
-#include <aidl/android/hardware/graphics/common/BufferUsage.h>
-#include <aidl/android/hardware/graphics/common/PixelFormat.h>
-#include <cutils/android_filesystem_config.h>
-
-#include <set>
-#include <string_view>
-
-namespace {
-
-using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
-using ::aidl::android::hardware::graphics::common::BufferUsage;
-using ::ndk::ScopedAStatus;
-using std::chrono_literals::operator""s;
-
-// Constants
-constexpr std::chrono::seconds kEnumerationTimeout = 10s;
-constexpr uint64_t kInvalidDisplayId = std::numeric_limits<uint64_t>::max();
-const std::set<uid_t> kAllowedUids = {AID_AUTOMOTIVE_EVS, AID_SYSTEM, AID_ROOT};
-
-} // namespace
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-// NOTE: All members values are static so that all clients operate on the same state
-// That is to say, this is effectively a singleton despite the fact that HIDL
-// constructs a new instance for each client.
-std::unordered_map<std::string, EvsEnumerator::CameraRecord> EvsEnumerator::sCameraList;
-std::mutex EvsEnumerator::sLock;
-std::condition_variable EvsEnumerator::sCameraSignal;
-std::unique_ptr<ConfigManager> EvsEnumerator::sConfigManager;
-std::shared_ptr<ICarDisplayProxy> EvsEnumerator::sDisplayProxy;
-std::unordered_map<uint8_t, uint64_t> EvsEnumerator::sDisplayPortList;
-
-EvsEnumerator::ActiveDisplays& EvsEnumerator::mutableActiveDisplays() {
- static ActiveDisplays active_displays;
- return active_displays;
-}
-
-EvsEnumerator::EvsEnumerator(const std::shared_ptr<ICarDisplayProxy>& proxyService) {
- LOG(DEBUG) << "EvsEnumerator is created.";
-
- if (!sConfigManager) {
- /* loads and initializes ConfigManager in a separate thread */
- sConfigManager = ConfigManager::Create();
- }
-
- if (!sDisplayProxy) {
- /* sets a car-window service handle */
- sDisplayProxy = proxyService;
- }
-
- // Enumerate existing devices
- enumerateCameras();
- mInternalDisplayId = enumerateDisplays();
-}
-
-bool EvsEnumerator::checkPermission() {
- const auto uid = AIBinder_getCallingUid();
- if (kAllowedUids.find(uid) == kAllowedUids.end()) {
- LOG(ERROR) << "EVS access denied: "
- << "pid = " << AIBinder_getCallingPid() << ", uid = " << uid;
- return false;
- }
-
- return true;
-}
-
-void EvsEnumerator::enumerateCameras() {
- if (!sConfigManager) {
- return;
- }
-
- for (auto id : sConfigManager->getCameraIdList()) {
- CameraRecord rec(id.data());
- std::unique_ptr<ConfigManager::CameraInfo>& pInfo = sConfigManager->getCameraInfo(id);
- if (pInfo) {
- uint8_t* ptr = reinterpret_cast<uint8_t*>(pInfo->characteristics);
- const size_t len = get_camera_metadata_size(pInfo->characteristics);
- rec.desc.metadata.insert(rec.desc.metadata.end(), ptr, ptr + len);
- }
- sCameraList.insert_or_assign(id, std::move(rec));
- }
-}
-
-uint64_t EvsEnumerator::enumerateDisplays() {
- LOG(INFO) << __FUNCTION__ << ": Starting display enumeration";
- uint64_t internalDisplayId = kInvalidDisplayId;
- if (!sDisplayProxy) {
- LOG(ERROR) << "ICarDisplayProxy is not available!";
- return internalDisplayId;
- }
-
- std::vector<int64_t> displayIds;
- if (auto status = sDisplayProxy->getDisplayIdList(&displayIds); !status.isOk()) {
- LOG(ERROR) << "Failed to retrieve a display id list"
- << ::android::statusToString(status.getStatus());
- return internalDisplayId;
- }
-
- if (displayIds.size() > 0) {
- // The first entry of the list is the internal display. See
- // SurfaceFlinger::getPhysicalDisplayIds() implementation.
- internalDisplayId = displayIds[0];
- for (const auto& id : displayIds) {
- const auto port = id & 0xFF;
- LOG(INFO) << "Display " << std::hex << id << " is detected on the port, " << port;
- sDisplayPortList.insert_or_assign(port, id);
- }
- }
-
- LOG(INFO) << "Found " << sDisplayPortList.size() << " displays";
- return internalDisplayId;
-}
-
-// Methods from ::android::hardware::automotive::evs::IEvsEnumerator follow.
-ScopedAStatus EvsEnumerator::getCameraList(std::vector<CameraDesc>* _aidl_return) {
- LOG(DEBUG) << __FUNCTION__;
- if (!checkPermission()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::PERMISSION_DENIED));
- }
-
- {
- std::unique_lock<std::mutex> lock(sLock);
- if (sCameraList.size() < 1) {
- // No qualified device has been found. Wait until new device is ready,
- // for 10 seconds.
- if (!sCameraSignal.wait_for(lock, kEnumerationTimeout,
- [] { return sCameraList.size() > 0; })) {
- LOG(DEBUG) << "Timer expired. No new device has been added.";
- }
- }
- }
-
- // Build up a packed array of CameraDesc for return
- _aidl_return->resize(sCameraList.size());
- unsigned i = 0;
- for (const auto& [key, cam] : sCameraList) {
- (*_aidl_return)[i++] = cam.desc;
- }
-
- if (sConfigManager) {
- // Adding camera groups that represent logical camera devices
- auto camGroups = sConfigManager->getCameraGroupIdList();
- for (auto&& id : camGroups) {
- if (sCameraList.find(id) != sCameraList.end()) {
- // Already exists in the _aidl_return
- continue;
- }
-
- std::unique_ptr<ConfigManager::CameraGroupInfo>& tempInfo =
- sConfigManager->getCameraGroupInfo(id);
- CameraRecord cam(id.data());
- if (tempInfo) {
- uint8_t* ptr = reinterpret_cast<uint8_t*>(tempInfo->characteristics);
- const size_t len = get_camera_metadata_size(tempInfo->characteristics);
- cam.desc.metadata.insert(cam.desc.metadata.end(), ptr, ptr + len);
- }
-
- sCameraList.insert_or_assign(id, cam);
- _aidl_return->push_back(cam.desc);
- }
- }
-
- // Send back the results
- LOG(DEBUG) << "Reporting " << sCameraList.size() << " cameras available";
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsEnumerator::getStreamList(const CameraDesc& desc,
- std::vector<Stream>* _aidl_return) {
- using AidlPixelFormat = ::aidl::android::hardware::graphics::common::PixelFormat;
-
- camera_metadata_t* pMetadata = const_cast<camera_metadata_t*>(
- reinterpret_cast<const camera_metadata_t*>(desc.metadata.data()));
- camera_metadata_entry_t streamConfig;
- if (!find_camera_metadata_entry(pMetadata, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
- &streamConfig)) {
- const unsigned numStreamConfigs = streamConfig.count / sizeof(StreamConfiguration);
- _aidl_return->resize(numStreamConfigs);
- const StreamConfiguration* pCurrentConfig =
- reinterpret_cast<StreamConfiguration*>(streamConfig.data.i32);
- for (unsigned i = 0; i < numStreamConfigs; ++i, ++pCurrentConfig) {
- // Build ::aidl::android::hardware::automotive::evs::Stream from
- // StreamConfiguration.
- Stream current = {
- .id = pCurrentConfig->id,
- .streamType =
- pCurrentConfig->type ==
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT
- ? StreamType::INPUT
- : StreamType::OUTPUT,
- .width = pCurrentConfig->width,
- .height = pCurrentConfig->height,
- .format = static_cast<AidlPixelFormat>(pCurrentConfig->format),
- .usage = BufferUsage::CAMERA_INPUT,
- .rotation = Rotation::ROTATION_0,
- };
-
- (*_aidl_return)[i] = current;
- }
- }
-
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsEnumerator::openCamera(const std::string& id, const Stream& cfg,
- std::shared_ptr<IEvsCamera>* obj) {
- LOG(DEBUG) << __FUNCTION__;
- if (!checkPermission()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::PERMISSION_DENIED));
- }
-
- // Is this a recognized camera id?
- CameraRecord* pRecord = findCameraById(id);
- if (!pRecord) {
- LOG(ERROR) << id << " does not exist!";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
- }
-
- // Has this camera already been instantiated by another caller?
- std::shared_ptr<EvsMockCamera> pActiveCamera = pRecord->activeInstance.lock();
- if (pActiveCamera) {
- LOG(WARNING) << "Killing previous camera because of new caller";
- closeCamera(pActiveCamera);
- }
-
- // Construct a camera instance for the caller
- if (!sConfigManager) {
- pActiveCamera = EvsMockCamera::Create(id.data());
- } else {
- pActiveCamera = EvsMockCamera::Create(id.data(), sConfigManager->getCameraInfo(id), &cfg);
- }
-
- pRecord->activeInstance = pActiveCamera;
- if (!pActiveCamera) {
- LOG(ERROR) << "Failed to create new EvsMockCamera object for " << id;
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
- }
-
- *obj = pActiveCamera;
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsEnumerator::closeCamera(const std::shared_ptr<IEvsCamera>& cameraObj) {
- LOG(DEBUG) << __FUNCTION__;
-
- if (!cameraObj) {
- LOG(ERROR) << "Ignoring call to closeCamera with null camera ptr";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
- }
-
- // Get the camera id so we can find it in our list
- CameraDesc desc;
- auto status = cameraObj->getCameraInfo(&desc);
- if (!status.isOk()) {
- LOG(ERROR) << "Failed to read a camera descriptor";
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
- }
- auto cameraId = desc.id;
- closeCamera_impl(cameraObj, cameraId);
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsEnumerator::openDisplay(int32_t id, std::shared_ptr<IEvsDisplay>* displayObj) {
- LOG(DEBUG) << __FUNCTION__;
- if (!checkPermission()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::PERMISSION_DENIED));
- }
-
- auto& displays = mutableActiveDisplays();
-
- if (auto existing_display_search = displays.popDisplay(id)) {
- // If we already have a display active, then we need to shut it down so we can
- // give exclusive access to the new caller.
- std::shared_ptr<EvsGlDisplay> pActiveDisplay = existing_display_search->displayWeak.lock();
- if (pActiveDisplay) {
- LOG(WARNING) << "Killing previous display because of new caller";
- pActiveDisplay->forceShutdown();
- }
- }
-
- // Create a new display interface and return it
- uint64_t targetDisplayId = mInternalDisplayId;
- auto it = sDisplayPortList.find(id);
- if (it != sDisplayPortList.end()) {
- targetDisplayId = it->second;
- } else {
- LOG(WARNING) << "No display is available on the port " << static_cast<int32_t>(id)
- << ". The main display " << mInternalDisplayId << " will be used instead";
- }
-
- // Create a new display interface and return it.
- std::shared_ptr<EvsGlDisplay> pActiveDisplay =
- ndk::SharedRefBase::make<EvsGlDisplay>(sDisplayProxy, targetDisplayId);
-
- if (auto insert_result = displays.tryInsert(id, pActiveDisplay); !insert_result) {
- LOG(ERROR) << "Display ID " << id << " has been used by another caller.";
- pActiveDisplay->forceShutdown();
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::RESOURCE_BUSY));
- }
-
- LOG(DEBUG) << "Returning new EvsGlDisplay object " << pActiveDisplay.get();
- *displayObj = pActiveDisplay;
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsEnumerator::closeDisplay(const std::shared_ptr<IEvsDisplay>& obj) {
- LOG(DEBUG) << __FUNCTION__;
-
- auto& displays = mutableActiveDisplays();
- const auto display_search = displays.popDisplay(obj);
-
- if (!display_search) {
- LOG(WARNING) << "Ignoring close of previously orphaned display - why did a client steal?";
- return ScopedAStatus::ok();
- }
-
- auto pActiveDisplay = display_search->displayWeak.lock();
-
- if (!pActiveDisplay) {
- LOG(ERROR) << "Somehow a display is being destroyed "
- << "when the enumerator didn't know one existed";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
- }
-
- pActiveDisplay->forceShutdown();
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsEnumerator::getDisplayState(DisplayState* state) {
- LOG(DEBUG) << __FUNCTION__;
- if (!checkPermission()) {
- *state = DisplayState::DEAD;
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::PERMISSION_DENIED));
- }
-
- // TODO(b/262779341): For now we can just return the state of the 1st display. Need to update
- // the API later.
-
- const auto& all_displays = mutableActiveDisplays().getAllDisplays();
-
- // Do we still have a display object we think should be active?
- if (all_displays.empty()) {
- *state = DisplayState::NOT_OPEN;
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
- }
-
- std::shared_ptr<IEvsDisplay> pActiveDisplay = all_displays.begin()->second.displayWeak.lock();
- if (pActiveDisplay) {
- return pActiveDisplay->getDisplayState(state);
- } else {
- *state = DisplayState::NOT_OPEN;
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
- }
-}
-
-ScopedAStatus EvsEnumerator::getDisplayIdList(std::vector<uint8_t>* list) {
- std::vector<uint8_t>& output = *list;
- if (sDisplayPortList.size() > 0) {
- output.resize(sDisplayPortList.size());
- unsigned i = 0;
- output[i++] = mInternalDisplayId & 0xFF;
- for (const auto& [port, id] : sDisplayPortList) {
- if (mInternalDisplayId != id) {
- output[i++] = port;
- }
- }
- }
-
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsEnumerator::isHardware(bool* flag) {
- *flag = true;
- return ScopedAStatus::ok();
-}
-
-void EvsEnumerator::notifyDeviceStatusChange(const std::string_view& deviceName,
- DeviceStatusType type) {
- std::lock_guard lock(sLock);
- if (!mCallback) {
- return;
- }
-
- std::vector<DeviceStatus> status{{.id = std::string(deviceName), .status = type}};
- if (!mCallback->deviceStatusChanged(status).isOk()) {
- LOG(WARNING) << "Failed to notify a device status change, name = " << deviceName
- << ", type = " << static_cast<int>(type);
- }
-}
-
-ScopedAStatus EvsEnumerator::registerStatusCallback(
- const std::shared_ptr<IEvsEnumeratorStatusCallback>& callback) {
- std::lock_guard lock(sLock);
- if (mCallback) {
- LOG(INFO) << "Replacing an existing device status callback";
- }
- mCallback = callback;
- return ScopedAStatus::ok();
-}
-
-void EvsEnumerator::closeCamera_impl(const std::shared_ptr<IEvsCamera>& pCamera,
- const std::string& cameraId) {
- // Find the named camera
- CameraRecord* pRecord = findCameraById(cameraId);
-
- // Is the display being destroyed actually the one we think is active?
- if (!pRecord) {
- LOG(ERROR) << "Asked to close a camera whose name isn't recognized";
- } else {
- std::shared_ptr<EvsMockCamera> pActiveCamera = pRecord->activeInstance.lock();
- if (!pActiveCamera) {
- LOG(WARNING) << "Somehow a camera is being destroyed "
- << "when the enumerator didn't know one existed";
- } else if (pActiveCamera != pCamera) {
- // This can happen if the camera was aggressively reopened,
- // orphaning this previous instance
- LOG(WARNING) << "Ignoring close of previously orphaned camera "
- << "- why did a client steal?";
- } else {
- // Shutdown the active camera
- pActiveCamera->shutdown();
- }
- }
-
- return;
-}
-
-EvsEnumerator::CameraRecord* EvsEnumerator::findCameraById(const std::string& cameraId) {
- // Find the named camera
- auto found = sCameraList.find(cameraId);
- if (found != sCameraList.end()) {
- // Found a match!
- return &found->second;
- }
-
- // We didn't find a match
- return nullptr;
-}
-
-std::optional<EvsEnumerator::ActiveDisplays::DisplayInfo> EvsEnumerator::ActiveDisplays::popDisplay(
- int32_t id) {
- std::lock_guard lck(mMutex);
- const auto search = mIdToDisplay.find(id);
- if (search == mIdToDisplay.end()) {
- return std::nullopt;
- }
- const auto display_info = search->second;
- mIdToDisplay.erase(search);
- mDisplayToId.erase(display_info.internalDisplayRawAddr);
- return display_info;
-}
-
-std::optional<EvsEnumerator::ActiveDisplays::DisplayInfo> EvsEnumerator::ActiveDisplays::popDisplay(
- const std::shared_ptr<IEvsDisplay>& display) {
- const auto display_ptr_val = reinterpret_cast<uintptr_t>(display.get());
- std::lock_guard lck(mMutex);
- const auto display_to_id_search = mDisplayToId.find(display_ptr_val);
- if (display_to_id_search == mDisplayToId.end()) {
- LOG(ERROR) << "Unknown display.";
- return std::nullopt;
- }
- const auto id = display_to_id_search->second;
- const auto id_to_display_search = mIdToDisplay.find(id);
- mDisplayToId.erase(display_to_id_search);
- if (id_to_display_search == mIdToDisplay.end()) {
- LOG(ERROR) << "No correspsonding ID for the display, probably orphaned.";
- return std::nullopt;
- }
- const auto display_info = id_to_display_search->second;
- mIdToDisplay.erase(id);
- return display_info;
-}
-
-std::unordered_map<int32_t, EvsEnumerator::ActiveDisplays::DisplayInfo>
-EvsEnumerator::ActiveDisplays::getAllDisplays() {
- std::lock_guard lck(mMutex);
- auto id_to_display_map_copy = mIdToDisplay;
- return id_to_display_map_copy;
-}
-
-bool EvsEnumerator::ActiveDisplays::tryInsert(int32_t id,
- const std::shared_ptr<EvsGlDisplay>& display) {
- std::lock_guard lck(mMutex);
- const auto display_ptr_val = reinterpret_cast<uintptr_t>(display.get());
-
- auto id_to_display_insert_result =
- mIdToDisplay.emplace(id, DisplayInfo{
- .id = id,
- .displayWeak = display,
- .internalDisplayRawAddr = display_ptr_val,
- });
- if (!id_to_display_insert_result.second) {
- return false;
- }
- auto display_to_id_insert_result = mDisplayToId.emplace(display_ptr_val, id);
- if (!display_to_id_insert_result.second) {
- mIdToDisplay.erase(id);
- return false;
- }
- return true;
-}
-
-ScopedAStatus EvsEnumerator::getUltrasonicsArrayList(
- [[maybe_unused]] std::vector<UltrasonicsArrayDesc>* list) {
- // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsEnumerator::openUltrasonicsArray(
- [[maybe_unused]] const std::string& id,
- [[maybe_unused]] std::shared_ptr<IEvsUltrasonicsArray>* obj) {
- // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsEnumerator::closeUltrasonicsArray(
- [[maybe_unused]] const std::shared_ptr<IEvsUltrasonicsArray>& obj) {
- // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
- return ScopedAStatus::ok();
-}
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
deleted file mode 100644
index e5f8e4c..0000000
--- a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "EvsGlDisplay.h"
-
-#include <aidl/android/hardware/automotive/evs/EvsResult.h>
-#include <aidl/android/hardware/graphics/common/BufferUsage.h>
-#include <aidl/android/hardware/graphics/common/PixelFormat.h>
-#include <aidlcommonsupport/NativeHandle.h>
-#include <android-base/thread_annotations.h>
-#include <linux/time.h>
-#include <ui/DisplayMode.h>
-#include <ui/DisplayState.h>
-#include <ui/GraphicBufferAllocator.h>
-#include <ui/GraphicBufferMapper.h>
-#include <utils/SystemClock.h>
-
-#include <chrono>
-
-namespace {
-
-using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
-using ::aidl::android::hardware::graphics::common::BufferUsage;
-using ::aidl::android::hardware::graphics::common::PixelFormat;
-using ::android::base::ScopedLockAssertion;
-using ::ndk::ScopedAStatus;
-
-constexpr auto kTimeout = std::chrono::seconds(1);
-
-bool debugFirstFrameDisplayed = false;
-
-int generateFingerPrint(buffer_handle_t handle) {
- return static_cast<int>(reinterpret_cast<long>(handle) & 0xFFFFFFFF);
-}
-
-} // namespace
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-EvsGlDisplay::EvsGlDisplay(const std::shared_ptr<ICarDisplayProxy>& pDisplayProxy,
- uint64_t displayId)
- : mDisplayId(displayId), mDisplayProxy(pDisplayProxy) {
- LOG(DEBUG) << "EvsGlDisplay instantiated";
-
- // Set up our self description
- // NOTE: These are arbitrary values chosen for testing
- mInfo.id = std::to_string(displayId);
- mInfo.vendorFlags = 3870;
-
- // Start a thread to render images on this display
- {
- std::lock_guard lock(mLock);
- mState = RUN;
- }
- mRenderThread = std::thread([this]() { renderFrames(); });
-}
-
-EvsGlDisplay::~EvsGlDisplay() {
- LOG(DEBUG) << "EvsGlDisplay being destroyed";
- forceShutdown();
-}
-
-/**
- * This gets called if another caller "steals" ownership of the display
- */
-void EvsGlDisplay::forceShutdown() {
- LOG(DEBUG) << "EvsGlDisplay forceShutdown";
- {
- std::lock_guard lock(mLock);
-
- // If the buffer isn't being held by a remote client, release it now as an
- // optimization to release the resources more quickly than the destructor might
- // get called.
- if (mBuffer.handle != nullptr) {
- // Report if we're going away while a buffer is outstanding
- if (mBufferBusy || mState == RUN) {
- LOG(ERROR) << "EvsGlDisplay going down while client is holding a buffer";
- }
- mState = STOPPING;
- }
-
- // Put this object into an unrecoverable error state since somebody else
- // is going to own the display now.
- mRequestedState = DisplayState::DEAD;
- }
- mBufferReadyToRender.notify_all();
-
- if (mRenderThread.joinable()) {
- mRenderThread.join();
- }
-}
-
-/**
- * Initialize GL in the context of a caller's thread and prepare a graphic
- * buffer to use.
- */
-bool EvsGlDisplay::initializeGlContextLocked() {
- // Initialize our display window
- // NOTE: This will cause the display to become "VISIBLE" before a frame is actually
- // returned, which is contrary to the spec and will likely result in a black frame being
- // (briefly) shown.
- if (!mGlWrapper.initialize(mDisplayProxy, mDisplayId)) {
- // Report the failure
- LOG(ERROR) << "Failed to initialize GL display";
- return false;
- }
-
- // Assemble the buffer description we'll use for our render target
- static_assert(::aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888 ==
- static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(
- HAL_PIXEL_FORMAT_RGBA_8888));
- mBuffer.description = {
- .width = static_cast<int>(mGlWrapper.getWidth()),
- .height = static_cast<int>(mGlWrapper.getHeight()),
- .layers = 1,
- .format = PixelFormat::RGBA_8888,
- // FIXME: Below line is not using
- // ::aidl::android::hardware::graphics::common::BufferUsage because
- // BufferUsage enum does not support a bitwise-OR operation; they
- // should be BufferUsage::GPU_RENDER_TARGET |
- // BufferUsage::COMPOSER_OVERLAY
- .usage = static_cast<BufferUsage>(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER),
- };
-
- ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
- uint32_t stride = static_cast<uint32_t>(mBuffer.description.stride);
- buffer_handle_t handle = nullptr;
- const ::android::status_t result =
- alloc.allocate(mBuffer.description.width, mBuffer.description.height,
- static_cast<::android::PixelFormat>(mBuffer.description.format),
- mBuffer.description.layers,
- static_cast<uint64_t>(mBuffer.description.usage), &handle, &stride,
- /* requestorName= */ "EvsGlDisplay");
- mBuffer.description.stride = stride;
- mBuffer.fingerprint = generateFingerPrint(mBuffer.handle);
- if (result != ::android::NO_ERROR) {
- LOG(ERROR) << "Error " << result << " allocating " << mBuffer.description.width << " x "
- << mBuffer.description.height << " graphics buffer.";
- mGlWrapper.shutdown();
- return false;
- }
-
- mBuffer.handle = handle;
- if (mBuffer.handle == nullptr) {
- LOG(ERROR) << "We didn't get a buffer handle back from the allocator";
- mGlWrapper.shutdown();
- return false;
- }
-
- LOG(DEBUG) << "Allocated new buffer " << mBuffer.handle << " with stride "
- << mBuffer.description.stride;
- return true;
-}
-
-/**
- * This method runs in a separate thread and renders the contents of the buffer.
- */
-void EvsGlDisplay::renderFrames() {
- {
- std::lock_guard lock(mLock);
-
- if (!initializeGlContextLocked()) {
- LOG(ERROR) << "Failed to initialize GL context";
- return;
- }
-
- // Display buffer is ready.
- mBufferBusy = false;
- }
- mBufferReadyToUse.notify_all();
-
- while (true) {
- {
- std::unique_lock lock(mLock);
- ScopedLockAssertion lock_assertion(mLock);
- mBufferReadyToRender.wait(
- lock, [this]() REQUIRES(mLock) { return mBufferReady || mState != RUN; });
- if (mState != RUN) {
- LOG(DEBUG) << "A rendering thread is stopping";
- break;
- }
- mBufferReady = false;
- }
-
- // Update the texture contents with the provided data
- if (!mGlWrapper.updateImageTexture(mBuffer.handle, mBuffer.description)) {
- LOG(WARNING) << "Failed to update the image texture";
- continue;
- }
-
- // Put the image on the screen
- mGlWrapper.renderImageToScreen();
- if (!debugFirstFrameDisplayed) {
- LOG(DEBUG) << "EvsFirstFrameDisplayTiming start time: " << ::android::elapsedRealtime()
- << " ms.";
- debugFirstFrameDisplayed = true;
- }
-
- // Mark current frame is consumed.
- {
- std::lock_guard lock(mLock);
- mBufferBusy = false;
- }
- mBufferDone.notify_all();
- }
-
- LOG(DEBUG) << "A rendering thread is stopped.";
-
- // Drop the graphics buffer we've been using
- ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
- alloc.free(mBuffer.handle);
- mBuffer.handle = nullptr;
-
- mGlWrapper.hideWindow(mDisplayProxy, mDisplayId);
- mGlWrapper.shutdown();
-
- std::lock_guard lock(mLock);
- mState = STOPPED;
-}
-
-/**
- * Returns basic information about the EVS display provided by the system.
- * See the description of the DisplayDesc structure for details.
- */
-ScopedAStatus EvsGlDisplay::getDisplayInfo(DisplayDesc* _aidl_return) {
- if (!mDisplayProxy) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
- }
-
- ::aidl::android::frameworks::automotive::display::DisplayDesc proxyDisplay;
- auto status = mDisplayProxy->getDisplayInfo(mDisplayId, &proxyDisplay);
- if (!status.isOk()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
- }
-
- _aidl_return->width = proxyDisplay.width;
- _aidl_return->height = proxyDisplay.height;
- _aidl_return->orientation = static_cast<Rotation>(proxyDisplay.orientation);
- _aidl_return->id = mInfo.id; // FIXME: what should be ID here?
- _aidl_return->vendorFlags = mInfo.vendorFlags;
- return ::ndk::ScopedAStatus::ok();
-}
-
-/**
- * Clients may set the display state to express their desired state.
- * The HAL implementation must gracefully accept a request for any state
- * while in any other state, although the response may be to ignore the request.
- * The display is defined to start in the NOT_VISIBLE state upon initialization.
- * The client is then expected to request the VISIBLE_ON_NEXT_FRAME state, and
- * then begin providing video. When the display is no longer required, the client
- * is expected to request the NOT_VISIBLE state after passing the last video frame.
- */
-ScopedAStatus EvsGlDisplay::setDisplayState(DisplayState state) {
- LOG(DEBUG) << __FUNCTION__;
- std::lock_guard lock(mLock);
-
- if (mRequestedState == DisplayState::DEAD) {
- // This object no longer owns the display -- it's been superceeded!
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
- }
-
- // Ensure we recognize the requested state so we don't go off the rails
- static constexpr ::ndk::enum_range<DisplayState> kDisplayStateRange;
- if (std::find(kDisplayStateRange.begin(), kDisplayStateRange.end(), state) ==
- kDisplayStateRange.end()) {
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
- }
-
- switch (state) {
- case DisplayState::NOT_VISIBLE:
- mGlWrapper.hideWindow(mDisplayProxy, mDisplayId);
- break;
- case DisplayState::VISIBLE:
- mGlWrapper.showWindow(mDisplayProxy, mDisplayId);
- break;
- default:
- break;
- }
-
- // Record the requested state
- mRequestedState = state;
-
- return ScopedAStatus::ok();
-}
-
-/**
- * The HAL implementation should report the actual current state, which might
- * transiently differ from the most recently requested state. Note, however, that
- * the logic responsible for changing display states should generally live above
- * the device layer, making it undesirable for the HAL implementation to
- * spontaneously change display states.
- */
-ScopedAStatus EvsGlDisplay::getDisplayState(DisplayState* _aidl_return) {
- LOG(DEBUG) << __FUNCTION__;
- std::lock_guard lock(mLock);
- *_aidl_return = mRequestedState;
- return ScopedAStatus::ok();
-}
-
-/**
- * This call returns a handle to a frame buffer associated with the display.
- * This buffer may be locked and written to by software and/or GL. This buffer
- * must be returned via a call to returnTargetBufferForDisplay() even if the
- * display is no longer visible.
- */
-ScopedAStatus EvsGlDisplay::getTargetBuffer(BufferDesc* _aidl_return) {
- LOG(DEBUG) << __FUNCTION__;
- std::unique_lock lock(mLock);
- ScopedLockAssertion lock_assertion(mLock);
- if (mRequestedState == DisplayState::DEAD) {
- LOG(ERROR) << "Rejecting buffer request from object that lost ownership of the display.";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
- }
-
- // If we don't already have a buffer, allocate one now
- // mBuffer.memHandle is a type of buffer_handle_t, which is equal to
- // native_handle_t*.
- mBufferReadyToUse.wait(lock, [this]() REQUIRES(mLock) { return !mBufferBusy; });
-
- // Do we have a frame available?
- if (mBufferBusy) {
- // This means either we have a 2nd client trying to compete for buffers
- // (an unsupported mode of operation) or else the client hasn't returned
- // a previously issued buffer yet (they're behaving badly).
- // NOTE: We have to make the callback even if we have nothing to provide
- LOG(ERROR) << "getTargetBuffer called while no buffers available.";
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));
- }
-
- // Mark our buffer as busy
- mBufferBusy = true;
-
- // Send the buffer to the client
- LOG(VERBOSE) << "Providing display buffer handle " << mBuffer.handle;
-
- BufferDesc bufferDescToSend = {
- .buffer =
- {
- .handle = std::move(::android::dupToAidl(mBuffer.handle)),
- .description = mBuffer.description,
- },
- .pixelSizeBytes = 4, // RGBA_8888 is 4-byte-per-pixel format
- .bufferId = mBuffer.fingerprint,
- };
- *_aidl_return = std::move(bufferDescToSend);
-
- return ScopedAStatus::ok();
-}
-
-/**
- * This call tells the display that the buffer is ready for display.
- * The buffer is no longer valid for use by the client after this call.
- */
-ScopedAStatus EvsGlDisplay::returnTargetBufferForDisplay(const BufferDesc& buffer) {
- LOG(VERBOSE) << __FUNCTION__;
- std::unique_lock lock(mLock);
- ScopedLockAssertion lock_assertion(mLock);
-
- // Nobody should call us with a null handle
- if (buffer.buffer.handle.fds.size() < 1) {
- LOG(ERROR) << __FUNCTION__ << " called without a valid buffer handle.";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
- }
- if (buffer.bufferId != mBuffer.fingerprint) {
- LOG(ERROR) << "Got an unrecognized frame returned.";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
- }
- if (!mBufferBusy) {
- LOG(ERROR) << "A frame was returned with no outstanding frames.";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
- }
-
- // If we've been displaced by another owner of the display, then we can't do anything else
- if (mRequestedState == DisplayState::DEAD) {
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
- }
-
- // If we were waiting for a new frame, this is it!
- if (mRequestedState == DisplayState::VISIBLE_ON_NEXT_FRAME) {
- mRequestedState = DisplayState::VISIBLE;
- mGlWrapper.showWindow(mDisplayProxy, mDisplayId);
- }
-
- // Validate we're in an expected state
- if (mRequestedState != DisplayState::VISIBLE) {
- // Not sure why a client would send frames back when we're not visible.
- LOG(WARNING) << "Got a frame returned while not visible - ignoring.";
- return ScopedAStatus::ok();
- }
- mBufferReady = true;
- mBufferReadyToRender.notify_all();
-
- if (!mBufferDone.wait_for(lock, kTimeout, [this]() REQUIRES(mLock) { return !mBufferBusy; })) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
- }
-
- return ScopedAStatus::ok();
-}
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/EvsMockCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsMockCamera.cpp
deleted file mode 100644
index 4b46a5a..0000000
--- a/automotive/evs/aidl/impl/default/src/EvsMockCamera.cpp
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "EvsMockCamera.h"
-#include "ConfigManager.h"
-#include "EvsEnumerator.h"
-
-#include <aidlcommonsupport/NativeHandle.h>
-#include <ui/GraphicBufferAllocator.h>
-#include <ui/GraphicBufferMapper.h>
-#include <utils/SystemClock.h>
-
-#include <memory>
-
-namespace {
-
-using ::aidl::android::hardware::graphics::common::BufferUsage;
-using ::ndk::ScopedAStatus;
-
-// Arbitrary limit on number of graphics buffers allowed to be allocated
-// Safeguards against unreasonable resource consumption and provides a testable limit
-constexpr unsigned kMaxBuffersInFlight = 100;
-
-// Minimum number of buffers to run a video stream
-constexpr int kMinimumBuffersInFlight = 1;
-
-// Colors for the colorbar test pattern in ABGR format
-constexpr uint32_t kColors[] = {
- 0xFFFFFFFF, // white
- 0xFF00FFFF, // yellow
- 0xFFFFFF00, // cyan
- 0xFF00FF00, // green
- 0xFFFF00FF, // fuchsia
- 0xFF0000FF, // red
- 0xFFFF0000, // blue
- 0xFF000000, // black
-};
-constexpr size_t kNumColors = sizeof(kColors) / sizeof(kColors[0]);
-
-} // namespace
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-EvsMockCamera::EvsMockCamera([[maybe_unused]] Sigil sigil, const char* id,
- std::unique_ptr<ConfigManager::CameraInfo>& camInfo)
- : mFramesAllowed(0), mFramesInUse(0), mStreamState(STOPPED), mCameraInfo(camInfo) {
- LOG(DEBUG) << __FUNCTION__;
-
- /* set a camera id */
- mDescription.id = id;
-
- /* set camera metadata */
- if (camInfo) {
- uint8_t* ptr = reinterpret_cast<uint8_t*>(camInfo->characteristics);
- const size_t len = get_camera_metadata_size(camInfo->characteristics);
- mDescription.metadata.insert(mDescription.metadata.end(), ptr, ptr + len);
- }
-}
-
-EvsMockCamera::~EvsMockCamera() {
- LOG(DEBUG) << __FUNCTION__;
- shutdown();
-}
-
-// This gets called if another caller "steals" ownership of the camera
-void EvsMockCamera::shutdown() {
- LOG(DEBUG) << __FUNCTION__;
-
- // Make sure our output stream is cleaned up
- // (It really should be already)
- stopVideoStream_impl();
-
- // Claim the lock while we work on internal state
- std::lock_guard lock(mAccessLock);
-
- // Drop all the graphics buffers we've been using
- if (mBuffers.size() > 0) {
- ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
- for (auto&& rec : mBuffers) {
- if (rec.inUse) {
- LOG(WARNING) << "WARNING: releasing a buffer remotely owned.";
- }
- alloc.free(rec.handle);
- rec.handle = nullptr;
- }
- mBuffers.clear();
- }
-
- // Put this object into an unrecoverable error state since somebody else
- // is going to own the underlying camera now
- mStreamState = DEAD;
-}
-
-// Methods from ::aidl::android::hardware::automotive::evs::IEvsCamera follow.
-ScopedAStatus EvsMockCamera::getCameraInfo(CameraDesc* _aidl_return) {
- LOG(DEBUG) << __FUNCTION__;
-
- // Send back our self description
- *_aidl_return = mDescription;
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::setMaxFramesInFlight(int32_t bufferCount) {
- LOG(DEBUG) << __FUNCTION__ << ", bufferCount = " << bufferCount;
- ;
-
- std::lock_guard lock(mAccessLock);
-
- // If we've been displaced by another owner of the camera, then we can't do anything else
- if (mStreamState == DEAD) {
- LOG(ERROR) << "Ignoring setMaxFramesInFlight call when camera has been lost.";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
- }
-
- // We cannot function without at least one video buffer to send data
- if (bufferCount < 1) {
- LOG(ERROR) << "Ignoring setMaxFramesInFlight with less than one buffer requested.";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
- }
-
- // Update our internal state
- if (!setAvailableFrames_Locked(bufferCount)) {
- LOG(ERROR) << "Failed to adjust the maximum number of frames in flight.";
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));
- }
-
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::startVideoStream(const std::shared_ptr<IEvsCameraStream>& cb) {
- LOG(DEBUG) << __FUNCTION__;
-
- if (!cb) {
- LOG(ERROR) << "A given stream callback is invalid.";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
- }
-
- std::lock_guard lock(mAccessLock);
-
- // If we've been displaced by another owner of the camera, then we can't do anything else
- if (mStreamState == DEAD) {
- LOG(ERROR) << "Ignoring startVideoStream call when camera has been lost.";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
- }
-
- if (mStreamState != STOPPED) {
- LOG(ERROR) << "Ignoring startVideoStream call when a stream is already running.";
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::STREAM_ALREADY_RUNNING));
- }
-
- // If the client never indicated otherwise, configure ourselves for a single streaming buffer
- if (mFramesAllowed < kMinimumBuffersInFlight &&
- !setAvailableFrames_Locked(kMinimumBuffersInFlight)) {
- LOG(ERROR) << "Failed to start stream because we couldn't get a graphics buffer";
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));
- }
-
- // Record the user's callback for use when we have a frame ready
- mStream = cb;
-
- // Start the frame generation thread
- mStreamState = RUNNING;
- mCaptureThread = std::thread([this]() { generateFrames(); });
-
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::doneWithFrame(const std::vector<BufferDesc>& list) {
- std::lock_guard lock(mAccessLock);
- for (const auto& desc : list) {
- returnBufferLocked(desc.bufferId);
- }
-
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::stopVideoStream() {
- LOG(DEBUG) << __FUNCTION__;
- return stopVideoStream_impl();
-}
-
-ScopedAStatus EvsMockCamera::stopVideoStream_impl() {
- std::unique_lock lock(mAccessLock);
-
- if (mStreamState != RUNNING) {
- // Safely return here because a stream is not running.
- return ScopedAStatus::ok();
- }
-
- // Tell the GenerateFrames loop we want it to stop
- mStreamState = STOPPING;
-
- // Block outside the mutex until the "stop" flag has been acknowledged
- // We won't send any more frames, but the client might still get some already in flight
- LOG(DEBUG) << "Waiting for stream thread to end...";
- lock.unlock();
- if (mCaptureThread.joinable()) {
- mCaptureThread.join();
- }
- lock.lock();
-
- mStreamState = STOPPED;
- mStream = nullptr;
- LOG(DEBUG) << "Stream marked STOPPED.";
-
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::getExtendedInfo(int32_t opaqueIdentifier,
- std::vector<uint8_t>* opaqueValue) {
- const auto it = mExtInfo.find(opaqueIdentifier);
- if (it == mExtInfo.end()) {
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
- } else {
- *opaqueValue = mExtInfo[opaqueIdentifier];
- }
-
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::setExtendedInfo(int32_t opaqueIdentifier,
- const std::vector<uint8_t>& opaqueValue) {
- mExtInfo.insert_or_assign(opaqueIdentifier, opaqueValue);
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::getPhysicalCameraInfo([[maybe_unused]] const std::string& id,
- CameraDesc* _aidl_return) {
- LOG(DEBUG) << __FUNCTION__;
-
- // This method works exactly same as getCameraInfo() in EVS HW module.
- *_aidl_return = mDescription;
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::pauseVideoStream() {
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
-}
-
-ScopedAStatus EvsMockCamera::resumeVideoStream() {
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
-}
-
-ScopedAStatus EvsMockCamera::setPrimaryClient() {
- /* Because EVS HW module reference implementation expects a single client at
- * a time, this returns a success code always.
- */
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::forcePrimaryClient(const std::shared_ptr<IEvsDisplay>&) {
- /* Because EVS HW module reference implementation expects a single client at
- * a time, this returns a success code always.
- */
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::unsetPrimaryClient() {
- /* Because EVS HW module reference implementation expects a single client at
- * a time, there is no chance that this is called by the secondary client and
- * therefore returns a success code always.
- */
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::getParameterList(std::vector<CameraParam>* _aidl_return) {
- if (mCameraInfo) {
- _aidl_return->resize(mCameraInfo->controls.size());
- auto idx = 0;
- for (auto& [name, range] : mCameraInfo->controls) {
- (*_aidl_return)[idx++] = name;
- }
- }
-
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus EvsMockCamera::getIntParameterRange([[maybe_unused]] CameraParam id,
- [[maybe_unused]] ParameterRange* _aidl_return) {
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
-}
-
-ScopedAStatus EvsMockCamera::setIntParameter(
- [[maybe_unused]] CameraParam id, [[maybe_unused]] int32_t value,
- [[maybe_unused]] std::vector<int32_t>* effectiveValue) {
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
-}
-
-ScopedAStatus EvsMockCamera::getIntParameter([[maybe_unused]] CameraParam id,
- [[maybe_unused]] std::vector<int32_t>* value) {
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
-}
-
-ScopedAStatus EvsMockCamera::importExternalBuffers(
- [[maybe_unused]] const std::vector<BufferDesc>& buffers,
- [[maybe_unused]] int32_t* _aidl_return) {
- LOG(DEBUG) << "This implementation does not support an external buffer import.";
- return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
-}
-
-bool EvsMockCamera::setAvailableFrames_Locked(unsigned bufferCount) {
- if (bufferCount < 1) {
- LOG(ERROR) << "Ignoring request to set buffer count to zero";
- return false;
- }
- if (bufferCount > kMaxBuffersInFlight) {
- LOG(ERROR) << "Rejecting buffer request in excess of internal limit";
- return false;
- }
-
- // Is an increase required?
- if (mFramesAllowed < bufferCount) {
- // An increase is required
- auto needed = bufferCount - mFramesAllowed;
- LOG(INFO) << "Allocating " << needed << " buffers for camera frames";
-
- auto added = increaseAvailableFrames_Locked(needed);
- if (added != needed) {
- // If we didn't add all the frames we needed, then roll back to the previous state
- LOG(ERROR) << "Rolling back to previous frame queue size";
- decreaseAvailableFrames_Locked(added);
- return false;
- }
- } else if (mFramesAllowed > bufferCount) {
- // A decrease is required
- auto framesToRelease = mFramesAllowed - bufferCount;
- LOG(INFO) << "Returning " << framesToRelease << " camera frame buffers";
-
- auto released = decreaseAvailableFrames_Locked(framesToRelease);
- if (released != framesToRelease) {
- // This shouldn't happen with a properly behaving client because the client
- // should only make this call after returning sufficient outstanding buffers
- // to allow a clean resize.
- LOG(ERROR) << "Buffer queue shrink failed -- too many buffers currently in use?";
- }
- }
-
- return true;
-}
-
-unsigned EvsMockCamera::increaseAvailableFrames_Locked(unsigned numToAdd) {
- // Acquire the graphics buffer allocator
- ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
-
- unsigned added = 0;
- while (added < numToAdd) {
- unsigned pixelsPerLine = 0;
- buffer_handle_t memHandle = nullptr;
- auto result = alloc.allocate(mWidth, mHeight, mFormat, 1, mUsage, &memHandle,
- &pixelsPerLine, 0, "EvsMockCamera");
- if (result != ::android::NO_ERROR) {
- LOG(ERROR) << "Error " << result << " allocating " << mWidth << " x " << mHeight
- << " graphics buffer";
- break;
- }
- if (memHandle == nullptr) {
- LOG(ERROR) << "We didn't get a buffer handle back from the allocator";
- break;
- }
- if (mStride > 0) {
- if (mStride != pixelsPerLine) {
- LOG(ERROR) << "We did not expect to get buffers with different strides!";
- }
- } else {
- // Gralloc defines stride in terms of pixels per line
- mStride = pixelsPerLine;
- }
-
- // Find a place to store the new buffer
- auto stored = false;
- for (auto&& rec : mBuffers) {
- if (rec.handle == nullptr) {
- // Use this existing entry
- rec.handle = memHandle;
- rec.inUse = false;
- stored = true;
- break;
- }
- }
- if (!stored) {
- // Add a BufferRecord wrapping this handle to our set of available buffers
- mBuffers.push_back(BufferRecord(memHandle));
- }
-
- ++mFramesAllowed;
- ++added;
- }
-
- return added;
-}
-
-unsigned EvsMockCamera::decreaseAvailableFrames_Locked(unsigned numToRemove) {
- // Acquire the graphics buffer allocator
- ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
-
- unsigned removed = 0;
- for (auto&& rec : mBuffers) {
- // Is this record not in use, but holding a buffer that we can free?
- if ((rec.inUse == false) && (rec.handle != nullptr)) {
- // Release buffer and update the record so we can recognize it as "empty"
- alloc.free(rec.handle);
- rec.handle = nullptr;
-
- --mFramesAllowed;
- ++removed;
-
- if (removed == numToRemove) {
- break;
- }
- }
- }
-
- return removed;
-}
-
-// This is the asynchronous frame generation thread that runs in parallel with the
-// main serving thread. There is one for each active camera instance.
-void EvsMockCamera::generateFrames() {
- LOG(DEBUG) << "Frame generation loop started.";
-
- unsigned idx = 0;
- while (true) {
- bool timeForFrame = false;
- const nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-
- // Lock scope for updating shared state
- {
- std::lock_guard lock(mAccessLock);
-
- if (mStreamState != RUNNING) {
- // Break out of our main thread loop
- break;
- }
-
- // Are we allowed to issue another buffer?
- if (mFramesInUse >= mFramesAllowed) {
- // Can't do anything right now -- skip this frame
- LOG(WARNING) << "Skipped a frame because too many are in flight.";
- } else {
- // Identify an available buffer to fill
- for (idx = 0; idx < mBuffers.size(); idx++) {
- if (!mBuffers[idx].inUse) {
- if (mBuffers[idx].handle != nullptr) {
- // Found an available record, so stop looking
- break;
- }
- }
- }
- if (idx >= mBuffers.size()) {
- // This shouldn't happen since we already checked mFramesInUse vs mFramesAllowed
- ALOGE("Failed to find an available buffer slot\n");
- } else {
- // We're going to make the frame busy
- mBuffers[idx].inUse = true;
- mFramesInUse++;
- timeForFrame = true;
- }
- }
- }
-
- if (timeForFrame) {
- using AidlPixelFormat = ::aidl::android::hardware::graphics::common::PixelFormat;
-
- // Assemble the buffer description we'll transmit below
- buffer_handle_t memHandle = mBuffers[idx].handle;
- BufferDesc newBuffer = {
- .buffer =
- {
- .description =
- {
- .width = static_cast<int32_t>(mWidth),
- .height = static_cast<int32_t>(mHeight),
- .layers = 1,
- .format = static_cast<AidlPixelFormat>(mFormat),
- .usage = static_cast<BufferUsage>(mUsage),
- .stride = static_cast<int32_t>(mStride),
- },
- .handle = ::android::dupToAidl(memHandle),
- },
- .bufferId = static_cast<int32_t>(idx),
- .deviceId = mDescription.id,
- .timestamp = static_cast<int64_t>(::android::elapsedRealtimeNano() *
- 1e+3), // timestamps is in microseconds
- };
-
- // Write test data into the image buffer
- fillMockFrame(memHandle, reinterpret_cast<const AHardwareBuffer_Desc*>(
- &newBuffer.buffer.description));
-
- // Issue the (asynchronous) callback to the client -- can't be holding the lock
- auto flag = false;
- if (mStream) {
- std::vector<BufferDesc> frames;
- frames.push_back(std::move(newBuffer));
- flag = mStream->deliverFrame(frames).isOk();
- }
-
- if (flag) {
- LOG(DEBUG) << "Delivered " << memHandle << ", id = " << mBuffers[idx].handle;
- } else {
- // This can happen if the client dies and is likely unrecoverable.
- // To avoid consuming resources generating failing calls, we stop sending
- // frames. Note, however, that the stream remains in the "STREAMING" state
- // until cleaned up on the main thread.
- LOG(ERROR) << "Frame delivery call failed in the transport layer.";
-
- // Since we didn't actually deliver it, mark the frame as available
- std::lock_guard<std::mutex> lock(mAccessLock);
- mBuffers[idx].inUse = false;
- mFramesInUse--;
- }
- }
-
- // We arbitrarily choose to generate frames at 15 fps to ensure we pass the 10fps test
- // requirement
- static const int kTargetFrameRate = 15;
- static const nsecs_t kTargetFrameIntervalUs = 1000 * 1000 / kTargetFrameRate;
- const nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- const nsecs_t elapsedTimeUs = (now - startTime) / 1000;
- const nsecs_t sleepDurationUs = kTargetFrameIntervalUs - elapsedTimeUs;
- if (sleepDurationUs > 0) {
- usleep(sleepDurationUs);
- }
- }
-
- // If we've been asked to stop, send an event to signal the actual end of stream
- EvsEventDesc event = {
- .aType = EvsEventType::STREAM_STOPPED,
- };
- if (!mStream->notify(event).isOk()) {
- ALOGE("Error delivering end of stream marker");
- }
-
- return;
-}
-
-void EvsMockCamera::fillMockFrame(buffer_handle_t handle, const AHardwareBuffer_Desc* pDesc) {
- // Lock our output buffer for writing
- uint32_t* pixels = nullptr;
- ::android::GraphicBufferMapper& mapper = ::android::GraphicBufferMapper::get();
- mapper.lock(handle, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_NEVER,
- ::android::Rect(pDesc->width, pDesc->height), (void**)&pixels);
-
- // If we failed to lock the pixel buffer, we're about to crash, but log it first
- if (!pixels) {
- ALOGE("Camera failed to gain access to image buffer for writing");
- return;
- }
-
- // Fill in the test pixels; the colorbar in ABGR format
- for (unsigned row = 0; row < pDesc->height; row++) {
- for (unsigned col = 0; col < pDesc->width; col++) {
- const uint32_t index = col * kNumColors / pDesc->width;
- pixels[col] = kColors[index];
- }
- // Point to the next row
- // NOTE: stride retrieved from gralloc is in units of pixels
- pixels = pixels + pDesc->stride;
- }
-
- // Release our output buffer
- mapper.unlock(handle);
-}
-
-void EvsMockCamera::returnBufferLocked(const uint32_t bufferId) {
- if (bufferId >= mBuffers.size()) {
- ALOGE("ignoring doneWithFrame called with invalid bufferId %d (max is %zu)", bufferId,
- mBuffers.size() - 1);
- return;
- }
-
- if (!mBuffers[bufferId].inUse) {
- ALOGE("ignoring doneWithFrame called on frame %d which is already free", bufferId);
- return;
- }
-
- // Mark the frame as available
- mBuffers[bufferId].inUse = false;
- mFramesInUse--;
-
- // If this frame's index is high in the array, try to move it down
- // to improve locality after mFramesAllowed has been reduced.
- if (bufferId >= mFramesAllowed) {
- // Find an empty slot lower in the array (which should always exist in this case)
- for (auto&& rec : mBuffers) {
- if (rec.handle == nullptr) {
- rec.handle = mBuffers[bufferId].handle;
- mBuffers[bufferId].handle = nullptr;
- break;
- }
- }
- }
-}
-
-std::shared_ptr<EvsMockCamera> EvsMockCamera::Create(const char* deviceName) {
- std::unique_ptr<ConfigManager::CameraInfo> nullCamInfo = nullptr;
-
- return Create(deviceName, nullCamInfo);
-}
-
-std::shared_ptr<EvsMockCamera> EvsMockCamera::Create(
- const char* deviceName, std::unique_ptr<ConfigManager::CameraInfo>& camInfo,
- [[maybe_unused]] const Stream* streamCfg) {
- std::shared_ptr<EvsMockCamera> c =
- ndk::SharedRefBase::make<EvsMockCamera>(Sigil{}, deviceName, camInfo);
- if (!c) {
- LOG(ERROR) << "Failed to instantiate EvsMockCamera.";
- return nullptr;
- }
-
- // Use the first resolution from the list for the testing
- // TODO(b/214835237): Uses a given Stream configuration to choose the best
- // stream configuration.
- auto it = camInfo->streamConfigurations.begin();
- c->mWidth = it->second.width;
- c->mHeight = it->second.height;
- c->mDescription.vendorFlags = 0xFFFFFFFF; // Arbitrary test value
-
- c->mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
- c->mUsage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE |
- GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY;
-
- return c;
-}
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/GlWrapper.cpp b/automotive/evs/aidl/impl/default/src/GlWrapper.cpp
deleted file mode 100644
index 0ee5ecb..0000000
--- a/automotive/evs/aidl/impl/default/src/GlWrapper.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "GlWrapper.h"
-
-#include <aidl/android/frameworks/automotive/display/DisplayDesc.h>
-#include <aidl/android/hardware/graphics/common/HardwareBufferDescription.h>
-#include <aidlcommonsupport/NativeHandle.h>
-#include <ui/DisplayMode.h>
-#include <ui/DisplayState.h>
-#include <ui/GraphicBuffer.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-
-#include <utility>
-
-namespace {
-
-using ::aidl::android::frameworks::automotive::display::DisplayDesc;
-using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
-using ::aidl::android::frameworks::automotive::display::Rotation;
-using ::aidl::android::hardware::common::NativeHandle;
-using ::aidl::android::hardware::graphics::common::HardwareBufferDescription;
-using ::android::GraphicBuffer;
-using ::android::sp;
-
-constexpr const char vertexShaderSource[] =
- "attribute vec4 pos; \n"
- "attribute vec2 tex; \n"
- "varying vec2 uv; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = pos; \n"
- " uv = tex; \n"
- "} \n";
-
-constexpr const char pixelShaderSource[] =
- "precision mediump float; \n"
- "uniform sampler2D tex; \n"
- "varying vec2 uv; \n"
- "void main() \n"
- "{ \n"
- " gl_FragColor = texture2D(tex, uv);\n"
- "} \n";
-
-const char* getEGLError(void) {
- switch (eglGetError()) {
- case EGL_SUCCESS:
- return "EGL_SUCCESS";
- case EGL_NOT_INITIALIZED:
- return "EGL_NOT_INITIALIZED";
- case EGL_BAD_ACCESS:
- return "EGL_BAD_ACCESS";
- case EGL_BAD_ALLOC:
- return "EGL_BAD_ALLOC";
- case EGL_BAD_ATTRIBUTE:
- return "EGL_BAD_ATTRIBUTE";
- case EGL_BAD_CONTEXT:
- return "EGL_BAD_CONTEXT";
- case EGL_BAD_CONFIG:
- return "EGL_BAD_CONFIG";
- case EGL_BAD_CURRENT_SURFACE:
- return "EGL_BAD_CURRENT_SURFACE";
- case EGL_BAD_DISPLAY:
- return "EGL_BAD_DISPLAY";
- case EGL_BAD_SURFACE:
- return "EGL_BAD_SURFACE";
- case EGL_BAD_MATCH:
- return "EGL_BAD_MATCH";
- case EGL_BAD_PARAMETER:
- return "EGL_BAD_PARAMETER";
- case EGL_BAD_NATIVE_PIXMAP:
- return "EGL_BAD_NATIVE_PIXMAP";
- case EGL_BAD_NATIVE_WINDOW:
- return "EGL_BAD_NATIVE_WINDOW";
- case EGL_CONTEXT_LOST:
- return "EGL_CONTEXT_LOST";
- default:
- return "Unknown error";
- }
-}
-
-// Given shader source, load and compile it
-GLuint loadShader(GLenum type, const char* shaderSrc) {
- // Create the shader object
- GLuint shader = glCreateShader(type);
- if (shader == 0) {
- return 0;
- }
-
- // Load and compile the shader
- glShaderSource(shader, 1, &shaderSrc, nullptr);
- glCompileShader(shader);
-
- // Verify the compilation worked as expected
- GLint compiled = 0;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
- if (!compiled) {
- LOG(ERROR) << "Error compiling shader";
-
- GLint size = 0;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
- if (size > 0) {
- // Get and report the error message
- char* infoLog = (char*)malloc(size);
- glGetShaderInfoLog(shader, size, nullptr, infoLog);
- LOG(ERROR) << " msg:" << std::endl << infoLog;
- free(infoLog);
- }
-
- glDeleteShader(shader);
- return 0;
- }
-
- return shader;
-}
-
-// Create a program object given vertex and pixels shader source
-GLuint buildShaderProgram(const char* vtxSrc, const char* pxlSrc) {
- GLuint program = glCreateProgram();
- if (program == 0) {
- LOG(ERROR) << "Failed to allocate program object";
- return 0;
- }
-
- // Compile the shaders and bind them to this program
- GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vtxSrc);
- if (vertexShader == 0) {
- LOG(ERROR) << "Failed to load vertex shader";
- glDeleteProgram(program);
- return 0;
- }
- GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pxlSrc);
- if (pixelShader == 0) {
- LOG(ERROR) << "Failed to load pixel shader";
- glDeleteProgram(program);
- glDeleteShader(vertexShader);
- return 0;
- }
- glAttachShader(program, vertexShader);
- glAttachShader(program, pixelShader);
-
- glBindAttribLocation(program, 0, "pos");
- glBindAttribLocation(program, 1, "tex");
-
- // Link the program
- glLinkProgram(program);
- GLint linked = 0;
- glGetProgramiv(program, GL_LINK_STATUS, &linked);
- if (!linked) {
- LOG(ERROR) << "Error linking program";
- GLint size = 0;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &size);
- if (size > 0) {
- // Get and report the error message
- char* infoLog = (char*)malloc(size);
- glGetProgramInfoLog(program, size, nullptr, infoLog);
- LOG(ERROR) << " msg: " << infoLog;
- free(infoLog);
- }
-
- glDeleteProgram(program);
- glDeleteShader(vertexShader);
- glDeleteShader(pixelShader);
- return 0;
- }
-
- return program;
-}
-
-::android::sp<HGraphicBufferProducer> convertNativeHandleToHGBP(const NativeHandle& aidlHandle) {
- native_handle_t* handle = ::android::dupFromAidl(aidlHandle);
- if (handle->numFds != 0 || handle->numInts < std::ceil(sizeof(size_t) / sizeof(int))) {
- LOG(ERROR) << "Invalid native handle";
- return nullptr;
- }
- ::android::hardware::hidl_vec<uint8_t> halToken;
- halToken.setToExternal(reinterpret_cast<uint8_t*>(const_cast<int*>(&(handle->data[1]))),
- handle->data[0]);
- ::android::sp<HGraphicBufferProducer> hgbp =
- HGraphicBufferProducer::castFrom(::android::retrieveHalInterface(halToken));
- return std::move(hgbp);
-}
-
-} // namespace
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-// Main entry point
-bool GlWrapper::initialize(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy,
- uint64_t displayId) {
- LOG(DEBUG) << __FUNCTION__;
-
- if (!pWindowProxy) {
- LOG(ERROR) << "Could not get ICarDisplayProxy.";
- return false;
- }
-
- DisplayDesc displayDesc;
- auto status = pWindowProxy->getDisplayInfo(displayId, &displayDesc);
- if (!status.isOk()) {
- LOG(ERROR) << "Failed to read the display information";
- return false;
- }
-
- mWidth = displayDesc.width;
- mHeight = displayDesc.height;
- if ((displayDesc.orientation != Rotation::ROTATION_0) &&
- (displayDesc.orientation != Rotation::ROTATION_180)) {
- std::swap(mWidth, mHeight);
- }
- LOG(INFO) << "Display resolution is " << mWidth << "x" << mHeight;
-
- NativeHandle aidlHandle;
- status = pWindowProxy->getHGraphicBufferProducer(displayId, &aidlHandle);
- if (!status.isOk()) {
- LOG(ERROR) << "Failed to get IGraphicBufferProducer from ICarDisplayProxy.";
- return false;
- }
-
- mGfxBufferProducer = convertNativeHandleToHGBP(aidlHandle);
- if (!mGfxBufferProducer) {
- LOG(ERROR) << "Failed to convert a NativeHandle to HGBP.";
- return false;
- }
-
- mSurfaceHolder = getSurfaceFromHGBP(mGfxBufferProducer);
- if (mSurfaceHolder == nullptr) {
- LOG(ERROR) << "Failed to get a Surface from HGBP.";
- return false;
- }
-
- mWindow = getNativeWindow(mSurfaceHolder.get());
- if (mWindow == nullptr) {
- LOG(ERROR) << "Failed to get a native window from Surface.";
- return false;
- }
-
- // Set up our OpenGL ES context associated with the default display
- mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (mDisplay == EGL_NO_DISPLAY) {
- LOG(ERROR) << "Failed to get egl display";
- return false;
- }
-
- EGLint major = 2;
- EGLint minor = 0;
- if (!eglInitialize(mDisplay, &major, &minor)) {
- LOG(ERROR) << "Failed to initialize EGL: " << getEGLError();
- return false;
- }
-
- const EGLint config_attribs[] = {
- // clang-format off
- // Tag Value
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_DEPTH_SIZE, 0,
- EGL_NONE
- // clang-format on
- };
-
- // Pick the default configuration without constraints (is this good enough?)
- EGLConfig egl_config = {0};
- EGLint numConfigs = -1;
- eglChooseConfig(mDisplay, config_attribs, &egl_config, 1, &numConfigs);
- if (numConfigs != 1) {
- LOG(ERROR) << "Didn't find a suitable format for our display window, " << getEGLError();
- return false;
- }
-
- // Create the EGL render target surface
- mSurface = eglCreateWindowSurface(mDisplay, egl_config, mWindow, nullptr);
- if (mSurface == EGL_NO_SURFACE) {
- LOG(ERROR) << "eglCreateWindowSurface failed, " << getEGLError();
- return false;
- }
-
- // Create the EGL context
- // NOTE: Our shader is (currently at least) written to require version 3, so this
- // is required.
- const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
- mContext = eglCreateContext(mDisplay, egl_config, EGL_NO_CONTEXT, context_attribs);
- if (mContext == EGL_NO_CONTEXT) {
- LOG(ERROR) << "Failed to create OpenGL ES Context: " << getEGLError();
- return false;
- }
-
- // Activate our render target for drawing
- if (!eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)) {
- LOG(ERROR) << "Failed to make the OpenGL ES Context current: " << getEGLError();
- return false;
- }
-
- // Create the shader program for our simple pipeline
- mShaderProgram = buildShaderProgram(vertexShaderSource, pixelShaderSource);
- if (!mShaderProgram) {
- LOG(ERROR) << "Failed to build shader program: " << getEGLError();
- return false;
- }
-
- // Create a GL texture that will eventually wrap our externally created texture surface(s)
- glGenTextures(1, &mTextureMap);
- if (mTextureMap <= 0) {
- LOG(ERROR) << "Didn't get a texture handle allocated: " << getEGLError();
- return false;
- }
-
- // Turn off mip-mapping for the created texture surface
- // (the inbound camera imagery doesn't have MIPs)
- glBindTexture(GL_TEXTURE_2D, mTextureMap);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- return true;
-}
-
-void GlWrapper::shutdown() {
- // Drop our device textures
- if (mKHRimage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mDisplay, mKHRimage);
- mKHRimage = EGL_NO_IMAGE_KHR;
- }
-
- // Release all GL resources
- if (eglGetCurrentContext() == mContext) {
- eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- eglDestroySurface(mDisplay, mSurface);
- eglDestroyContext(mDisplay, mContext);
- eglTerminate(mDisplay);
- mSurface = EGL_NO_SURFACE;
- mContext = EGL_NO_CONTEXT;
- mDisplay = EGL_NO_DISPLAY;
-
- // Release the window
- mSurfaceHolder = nullptr;
-}
-
-void GlWrapper::showWindow(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy, uint64_t id) {
- if (pWindowProxy) {
- pWindowProxy->showWindow(id);
- } else {
- LOG(ERROR) << "ICarDisplayProxy is not available.";
- }
-}
-
-void GlWrapper::hideWindow(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy, uint64_t id) {
- if (pWindowProxy) {
- pWindowProxy->hideWindow(id);
- } else {
- LOG(ERROR) << "ICarDisplayProxy is not available.";
- }
-}
-
-bool GlWrapper::updateImageTexture(buffer_handle_t handle,
- const HardwareBufferDescription& description) {
- if (mKHRimage != EGL_NO_IMAGE_KHR) {
- return true;
- }
-
- // Create a temporary GraphicBuffer to wrap the provided handle.
- sp<GraphicBuffer> pGfxBuffer =
- new GraphicBuffer(description.width, description.height,
- static_cast<::android::PixelFormat>(description.format),
- description.layers, static_cast<uint32_t>(description.usage),
- description.stride, const_cast<native_handle_t*>(handle),
- /* keepOwnership= */ false);
- if (!pGfxBuffer) {
- LOG(ERROR) << "Failed to allocate GraphicBuffer to wrap our native handle";
- return false;
- }
-
- // Get a GL compatible reference to the graphics buffer we've been given
- EGLint eglImageAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
- EGLClientBuffer cbuf = static_cast<EGLClientBuffer>(pGfxBuffer->getNativeBuffer());
- mKHRimage = eglCreateImageKHR(mDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, cbuf,
- eglImageAttributes);
- if (mKHRimage == EGL_NO_IMAGE_KHR) {
- LOG(ERROR) << "Error creating EGLImage: " << getEGLError();
- return false;
- }
-
- // Update the texture handle we already created to refer to this gralloc buffer
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, mTextureMap);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, static_cast<GLeglImageOES>(mKHRimage));
-
- return true;
-}
-
-void GlWrapper::renderImageToScreen() {
- // Set the viewport
- glViewport(0, 0, mWidth, mHeight);
-
- // Clear the color buffer
- glClearColor(0.1f, 0.5f, 0.1f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // Select our screen space simple texture shader
- glUseProgram(mShaderProgram);
-
- // Bind the texture and assign it to the shader's sampler
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, mTextureMap);
- GLint sampler = glGetUniformLocation(mShaderProgram, "tex");
- glUniform1i(sampler, 0);
-
- // We want our image to show up opaque regardless of alpha values
- glDisable(GL_BLEND);
-
- // Draw a rectangle on the screen
- GLfloat vertsCarPos[] = {
- // clang-format off
- -0.8, 0.8, 0.0f, // left top in window space
- 0.8, 0.8, 0.0f, // right top
- -0.8, -0.8, 0.0f, // left bottom
- 0.8, -0.8, 0.0f // right bottom
- // clang-format on
- };
-
- // NOTE: We didn't flip the image in the texture, so V=0 is actually the top of the image
- GLfloat vertsCarTex[] = {
- // clang-format off
- 0.0f, 0.0f, // left top
- 1.0f, 0.0f, // right top
- 0.0f, 1.0f, // left bottom
- 1.0f, 1.0f // right bottom
- // clang-format on
- };
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertsCarPos);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vertsCarTex);
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- // Clean up and flip the rendered result to the front so it is visible
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
-
- glFinish();
-
- if (eglSwapBuffers(mDisplay, mSurface) == EGL_FALSE) {
- LOG(WARNING) << "Failed to swap EGL buffers, " << getEGLError();
- }
-}
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/service.cpp b/automotive/evs/aidl/impl/default/src/service.cpp
index 7532d87..0a0913f 100644
--- a/automotive/evs/aidl/impl/default/src/service.cpp
+++ b/automotive/evs/aidl/impl/default/src/service.cpp
@@ -14,75 +14,38 @@
* limitations under the License.
*/
-#include "EvsEnumerator.h"
-#include "EvsGlDisplay.h"
+#define LOG_TAG "EvsService"
+
+#include <DefaultEvsEnumerator.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <utils/Log.h>
-#include <unistd.h>
+using ::aidl::android::hardware::automotive::evs::implementation::DefaultEvsEnumerator;
-#include <atomic>
-#include <cstdlib>
-#include <string_view>
+int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) {
+ std::shared_ptr<DefaultEvsEnumerator> vhal = ndk::SharedRefBase::make<DefaultEvsEnumerator>();
-namespace {
-
-using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
-using ::aidl::android::hardware::automotive::evs::implementation::EvsEnumerator;
-
-constexpr std::string_view kDisplayServiceInstanceName = "/default";
-constexpr std::string_view kHwInstanceName = "/hw/0";
-constexpr int kNumBinderThreads = 1;
-
-} // namespace
-
-int main() {
- LOG(INFO) << "EVS Hardware Enumerator service is starting";
-
- const std::string displayServiceInstanceName =
- std::string(ICarDisplayProxy::descriptor) + std::string(kDisplayServiceInstanceName);
- if (!AServiceManager_isDeclared(displayServiceInstanceName.data())) {
- // TODO: We may just want to disable EVS display.
- LOG(ERROR) << displayServiceInstanceName << " is required.";
- return EXIT_FAILURE;
- }
-
- std::shared_ptr<ICarDisplayProxy> displayService = ICarDisplayProxy::fromBinder(
- ::ndk::SpAIBinder(AServiceManager_waitForService(displayServiceInstanceName.data())));
- if (!displayService) {
- LOG(ERROR) << "Cannot use " << displayServiceInstanceName << ". Exiting.";
- return EXIT_FAILURE;
- }
-
- // Register our service -- if somebody is already registered by our name,
- // they will be killed (their thread pool will throw an exception).
- std::shared_ptr<EvsEnumerator> service =
- ndk::SharedRefBase::make<EvsEnumerator>(displayService);
- if (!service) {
- LOG(ERROR) << "Failed to instantiate the service";
- return EXIT_FAILURE;
- }
-
- const std::string instanceName =
- std::string(EvsEnumerator::descriptor) + std::string(kHwInstanceName);
- auto err = AServiceManager_addService(service->asBinder().get(), instanceName.data());
+ ALOGI("Registering as service...");
+ binder_exception_t err =
+ AServiceManager_addService(vhal->asBinder().get(), "android.hardware.automotive.evs");
if (err != EX_NONE) {
- LOG(ERROR) << "Failed to register " << instanceName << ", exception = " << err;
- return EXIT_FAILURE;
+ ALOGE("failed to register android.hardware.automotive.evs service, exception: %d", err);
+ return 1;
}
- if (!ABinderProcess_setThreadPoolMaxThreadCount(kNumBinderThreads)) {
- LOG(ERROR) << "Failed to set thread pool";
- return EXIT_FAILURE;
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
+ ALOGE("%s", "failed to set thread pool max thread count");
+ return 1;
}
-
ABinderProcess_startThreadPool();
- LOG(INFO) << "EVS Hardware Enumerator is ready";
+
+ ALOGI("Evs Service Ready");
ABinderProcess_joinThreadPool();
- // In normal operation, we don't expect the thread pool to exit
- LOG(INFO) << "EVS Hardware Enumerator is shutting down";
- return EXIT_SUCCESS;
+
+ ALOGI("Evs Service Exiting");
+
+ return 0;
}