diff options
Diffstat (limited to 'camera/provider/2.7/default')
7 files changed, 850 insertions, 0 deletions
diff --git a/camera/provider/2.7/default/Android.bp b/camera/provider/2.7/default/Android.bp new file mode 100644 index 0000000000..bd5da2dbfa --- /dev/null +++ b/camera/provider/2.7/default/Android.bp @@ -0,0 +1,111 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_library_shared { + name: "android.hardware.camera.provider@2.7-external", + proprietary: true, + srcs: ["ExternalCameraProviderImpl_2_7.cpp"], + shared_libs: [ + "android.hardware.camera.common@1.0", + "android.hardware.camera.device@1.0", + "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.3", + "android.hardware.camera.device@3.4", + "android.hardware.camera.device@3.5", + "android.hardware.camera.device@3.6", + "android.hardware.camera.provider@2.4", + "android.hardware.camera.provider@2.5", + "android.hardware.camera.provider@2.6", + "android.hardware.camera.provider@2.7", + "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@3.0", + "android.hardware.graphics.mapper@4.0", + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "camera.device@3.3-impl", + "camera.device@3.4-external-impl", + "camera.device@3.4-impl", + "camera.device@3.5-external-impl", + "camera.device@3.5-impl", + "camera.device@3.6-external-impl", + "libcamera_metadata", + "libcutils", + "libhardware", + "libhidlbase", + "liblog", + "libtinyxml2", + "libutils", + ], + static_libs: [ + "android.hardware.camera.common@1.0-helper", + ], + header_libs: [ + "camera.device@3.4-external-impl_headers", + "camera.device@3.5-external-impl_headers", + "camera.device@3.6-external-impl_headers", + ], + export_include_dirs: ["."], +} + +cc_defaults { + name: "camera_external_service_2_7_defaults", + defaults: ["hidl_defaults"], + proprietary: true, + relative_install_path: "hw", + srcs: ["external-service.cpp"], + compile_multilib: "32", + shared_libs: [ + "android.hardware.camera.common@1.0", + "android.hardware.camera.device@1.0", + "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.3", + "android.hardware.camera.device@3.4", + "android.hardware.camera.device@3.5", + "android.hardware.camera.provider@2.4", + "android.hardware.camera.provider@2.4-external", + "android.hardware.camera.provider@2.5", + "android.hardware.camera.provider@2.5-external", + "android.hardware.camera.provider@2.6", + "android.hardware.camera.provider@2.7", + "android.hardware.camera.provider@2.7-external", + "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@3.0", + "android.hardware.graphics.mapper@4.0", + "libbinder", + "libcamera_metadata", + "libhidlbase", + "liblog", + "libtinyxml2", + "libutils", + ], + static_libs: [ + "android.hardware.camera.common@1.0-helper", + ], + header_libs: [ + "camera.device@3.4-external-impl_headers", + "camera.device@3.4-impl_headers", + "camera.device@3.5-external-impl_headers", + "camera.device@3.5-impl_headers", + "camera.device@3.6-external-impl_headers", + ], +} + +cc_binary { + name: "android.hardware.camera.provider@2.7-external-service", + defaults: ["camera_external_service_2_7_defaults"], + init_rc: ["android.hardware.camera.provider@2.7-external-service.rc"], +} + +cc_binary { + name: "android.hardware.camera.provider@2.7-external-service-lazy", + overrides: ["android.hardware.camera.provider@2.7-external-service"], + defaults: ["camera_external_service_2_7_defaults"], + init_rc: ["android.hardware.camera.provider@2.7-external-service-lazy.rc"], + cflags: ["-DLAZY_SERVICE"], +} diff --git a/camera/provider/2.7/default/CameraProvider_2_7.h b/camera/provider/2.7/default/CameraProvider_2_7.h new file mode 100644 index 0000000000..c34905f3f3 --- /dev/null +++ b/camera/provider/2.7/default/CameraProvider_2_7.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2021 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_CAMERA_PROVIDER_V2_7_CAMERAPROVIDER_H +#define ANDROID_HARDWARE_CAMERA_PROVIDER_V2_7_CAMERAPROVIDER_H + +#include <android/hardware/camera/provider/2.6/ICameraProviderCallback.h> +#include <android/hardware/camera/provider/2.7/ICameraProvider.h> +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> + +namespace android { +namespace hardware { +namespace camera { +namespace provider { +namespace V2_7 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::camera::common::V1_0::CameraDeviceStatus; +using ::android::hardware::camera::common::V1_0::Status; +using ::android::hardware::camera::common::V1_0::TorchModeStatus; +using ::android::hardware::camera::common::V1_0::VendorTag; +using ::android::hardware::camera::common::V1_0::VendorTagSection; +using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; +using ::android::hardware::camera::provider::V2_5::DeviceState; +using ::android::hardware::camera::provider::V2_7::CameraIdAndStreamCombination; +using ::android::hardware::camera::provider::V2_7::ICameraProvider; +using ::android::hidl::base::V1_0::IBase; + +// Default recommended RPC thread count for camera provider implementations +const int HWBINDER_THREAD_COUNT = 6; + +template <typename IMPL> +struct CameraProvider : public ICameraProvider { + CameraProvider() : impl() {} + ~CameraProvider() {} + + // Caller must use this method to check if CameraProvider ctor failed + bool isInitFailed() { return impl.isInitFailed(); } + + // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow. + Return<Status> setCallback(const sp<ICameraProviderCallback>& callback) override { + return impl.setCallback(callback); + } + + Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override { + return impl.getVendorTags(_hidl_cb); + } + + Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override { + return impl.getCameraIdList(_hidl_cb); + } + + Return<void> isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) override { + return impl.isSetTorchModeSupported(_hidl_cb); + } + + Return<void> getCameraDeviceInterface_V1_x(const hidl_string& cameraDeviceName, + getCameraDeviceInterface_V1_x_cb _hidl_cb) override { + return impl.getCameraDeviceInterface_V1_x(cameraDeviceName, _hidl_cb); + } + + Return<void> getCameraDeviceInterface_V3_x(const hidl_string& cameraDeviceName, + getCameraDeviceInterface_V3_x_cb _hidl_cb) override { + return impl.getCameraDeviceInterface_V3_x(cameraDeviceName, _hidl_cb); + } + + // Methods from ::android::hardware::camera::provider::V2_5::ICameraProvider follow. + Return<void> notifyDeviceStateChange(hardware::hidl_bitfield<DeviceState> newState) override { + return impl.notifyDeviceStateChange(newState); + } + + // Methods from ::android::hardware::camera::provider::V2_7::ICameraProvider follow. + Return<void> getConcurrentStreamingCameraIds( + getConcurrentStreamingCameraIds_cb _hidl_cb) override { + return impl.getConcurrentStreamingCameraIds(_hidl_cb); + } + + Return<void> isConcurrentStreamCombinationSupported( + const hidl_vec< + ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination>& + configs, + isConcurrentStreamCombinationSupported_cb _hidl_cb) override { + return impl.isConcurrentStreamCombinationSupported(configs, _hidl_cb); + } + + Return<void> isConcurrentStreamCombinationSupported_2_7( + const hidl_vec<CameraIdAndStreamCombination>& configs, + isConcurrentStreamCombinationSupported_2_7_cb _hidl_cb) override { + return impl.isConcurrentStreamCombinationSupported_2_7(configs, _hidl_cb); + } + + private: + IMPL impl; +}; + +} // namespace implementation +} // namespace V2_7 +} // namespace provider +} // namespace camera +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_CAMERAPROVIDER_H
\ No newline at end of file diff --git a/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp b/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp new file mode 100644 index 0000000000..b63e3bb88b --- /dev/null +++ b/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2021 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. + */ + +#define LOG_TAG "CamPrvdr@2.7-external" +//#define LOG_NDEBUG 0 +#include <log/log.h> + +#include <cutils/properties.h> +#include <errno.h> +#include <linux/videodev2.h> +#include <sys/inotify.h> +#include <regex> +#include "ExternalCameraDevice_3_4.h" +#include "ExternalCameraDevice_3_5.h" +#include "ExternalCameraDevice_3_6.h" +#include "ExternalCameraProviderImpl_2_7.h" + +namespace android { +namespace hardware { +namespace camera { +namespace provider { +namespace V2_7 { +namespace implementation { + +namespace { +// "device@<version>/external/<id>" +const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/external/(.+)"); +const int kMaxDevicePathLen = 256; +const char* kDevicePath = "/dev/"; +constexpr char kPrefix[] = "video"; +constexpr int kPrefixLen = sizeof(kPrefix) - 1; +constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen + 1; + +bool matchDeviceName(int cameraIdOffset, const hidl_string& deviceName, std::string* deviceVersion, + std::string* cameraDevicePath) { + std::string deviceNameStd(deviceName.c_str()); + std::smatch sm; + if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) { + if (deviceVersion != nullptr) { + *deviceVersion = sm[1]; + } + if (cameraDevicePath != nullptr) { + *cameraDevicePath = "/dev/video" + std::to_string(std::stoi(sm[2]) - cameraIdOffset); + } + return true; + } + return false; +} + +} // anonymous namespace + +ExternalCameraProviderImpl_2_7::ExternalCameraProviderImpl_2_7() + : mCfg(ExternalCameraConfig::loadFromCfg()) { + mHotPlugThread = sp<HotplugThread>::make(this); + mHotPlugThread->run("ExtCamHotPlug", PRIORITY_BACKGROUND); + + mPreferredHal3MinorVersion = + property_get_int32("ro.vendor.camera.external.hal3TrebleMinorVersion", 4); + ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion); + switch (mPreferredHal3MinorVersion) { + case 4: + case 5: + case 6: + // OK + break; + default: + ALOGW("Unknown minor camera device HAL version %d in property " + "'camera.external.hal3TrebleMinorVersion', defaulting to 4", + mPreferredHal3MinorVersion); + mPreferredHal3MinorVersion = 4; + } +} + +ExternalCameraProviderImpl_2_7::~ExternalCameraProviderImpl_2_7() { + mHotPlugThread->requestExit(); +} + +Return<Status> ExternalCameraProviderImpl_2_7::setCallback( + const sp<ICameraProviderCallback>& callback) { + Mutex::Autolock _l(mLock); + mCallbacks = callback; + if (mCallbacks == nullptr) { + return Status::OK; + } + // Send a callback for all devices to initialize + { + for (const auto& pair : mCameraStatusMap) { + mCallbacks->cameraDeviceStatusChange(pair.first, pair.second); + } + } + + return Status::OK; +} + +Return<void> ExternalCameraProviderImpl_2_7::getVendorTags( + ICameraProvider::getVendorTags_cb _hidl_cb) { + // No vendor tag support for USB camera + hidl_vec<VendorTagSection> zeroSections; + _hidl_cb(Status::OK, zeroSections); + return Void(); +} + +Return<void> ExternalCameraProviderImpl_2_7::getCameraIdList( + ICameraProvider::getCameraIdList_cb _hidl_cb) { + // External camera HAL always report 0 camera, and extra cameras + // are just reported via cameraDeviceStatusChange callbacks + hidl_vec<hidl_string> hidlDeviceNameList; + _hidl_cb(Status::OK, hidlDeviceNameList); + return Void(); +} + +void ExternalCameraProviderImpl_2_7::updateAttachedCameras() { + ALOGV("%s start scaning for existing V4L2 devices", __FUNCTION__); + // Find existing /dev/video* devices + DIR* devdir = opendir(kDevicePath); + if (devdir == 0) { + ALOGE("%s: cannot open %s! Exiting threadloop", __FUNCTION__, kDevicePath); + return; + } + + struct dirent* de; + while ((de = readdir(devdir)) != 0) { + // Find external v4l devices that's existing before we start watching and add them + if (!strncmp(kPrefix, de->d_name, kPrefixLen)) { + // TODO: This might reject some valid devices. Ex: internal is 33 and a device named 3 + // is added. + std::string deviceId(de->d_name + kPrefixLen); + if (mCfg.mInternalDevices.count(deviceId) == 0) { + ALOGV("Non-internal v4l device %s found", de->d_name); + char v4l2DevicePath[kMaxDevicePathLen]; + snprintf(v4l2DevicePath, kMaxDevicePathLen, "%s%s", kDevicePath, de->d_name); + deviceAdded(v4l2DevicePath); + } + } + } + closedir(devdir); +} + +Return<void> ExternalCameraProviderImpl_2_7::isSetTorchModeSupported( + ICameraProvider::isSetTorchModeSupported_cb _hidl_cb) { + // setTorchMode API is supported, though right now no external camera device + // has a flash unit. + _hidl_cb(Status::OK, true); + return Void(); +} + +Return<void> ExternalCameraProviderImpl_2_7::getCameraDeviceInterface_V1_x( + const hidl_string&, ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb) { + // External Camera HAL does not support HAL1 + _hidl_cb(Status::OPERATION_NOT_SUPPORTED, nullptr); + return Void(); +} + +Return<void> ExternalCameraProviderImpl_2_7::getCameraDeviceInterface_V3_x( + const hidl_string& cameraDeviceName, + ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb) { + std::string cameraDevicePath, deviceVersion; + bool match = matchDeviceName(mCfg.cameraIdOffset, cameraDeviceName, &deviceVersion, + &cameraDevicePath); + if (!match) { + _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); + return Void(); + } + + if (mCameraStatusMap.count(cameraDeviceName) == 0 || + mCameraStatusMap[cameraDeviceName] != CameraDeviceStatus::PRESENT) { + _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); + return Void(); + } + + sp<device::V3_4::implementation::ExternalCameraDevice> deviceImpl; + switch (mPreferredHal3MinorVersion) { + case 4: { + ALOGV("Constructing v3.4 external camera device"); + deviceImpl = + new device::V3_4::implementation::ExternalCameraDevice(cameraDevicePath, mCfg); + break; + } + case 5: { + ALOGV("Constructing v3.5 external camera device"); + deviceImpl = + new device::V3_5::implementation::ExternalCameraDevice(cameraDevicePath, mCfg); + break; + } + case 6: { + ALOGV("Constructing v3.6 external camera device"); + deviceImpl = + new device::V3_6::implementation::ExternalCameraDevice(cameraDevicePath, mCfg); + break; + } + default: + ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion); + _hidl_cb(Status::INTERNAL_ERROR, nullptr); + return Void(); + } + + if (deviceImpl == nullptr || deviceImpl->isInitFailed()) { + ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraDevicePath.c_str()); + _hidl_cb(Status::INTERNAL_ERROR, nullptr); + return Void(); + } + + IF_ALOGV() { + deviceImpl->getInterface()->interfaceChain( + [](::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) { + ALOGV("Device interface chain:"); + for (auto iface : interfaceChain) { + ALOGV(" %s", iface.c_str()); + } + }); + } + + _hidl_cb(Status::OK, deviceImpl->getInterface()); + + return Void(); +} + +void ExternalCameraProviderImpl_2_7::addExternalCamera(const char* devName) { + ALOGV("ExtCam: adding %s to External Camera HAL!", devName); + Mutex::Autolock _l(mLock); + std::string deviceName; + std::string cameraId = + std::to_string(mCfg.cameraIdOffset + std::atoi(devName + kDevicePrefixLen)); + if (mPreferredHal3MinorVersion == 6) { + deviceName = std::string("device@3.6/external/") + cameraId; + } else if (mPreferredHal3MinorVersion == 5) { + deviceName = std::string("device@3.5/external/") + cameraId; + } else { + deviceName = std::string("device@3.4/external/") + cameraId; + } + mCameraStatusMap[deviceName] = CameraDeviceStatus::PRESENT; + if (mCallbacks != nullptr) { + mCallbacks->cameraDeviceStatusChange(deviceName, CameraDeviceStatus::PRESENT); + } +} + +void ExternalCameraProviderImpl_2_7::deviceAdded(const char* devName) { + { + base::unique_fd fd(::open(devName, O_RDWR)); + if (fd.get() < 0) { + ALOGE("%s open v4l2 device %s failed:%s", __FUNCTION__, devName, strerror(errno)); + return; + } + + struct v4l2_capability capability; + int ret = ioctl(fd.get(), VIDIOC_QUERYCAP, &capability); + if (ret < 0) { + ALOGE("%s v4l2 QUERYCAP %s failed", __FUNCTION__, devName); + return; + } + + if (!(capability.device_caps & V4L2_CAP_VIDEO_CAPTURE)) { + ALOGW("%s device %s does not support VIDEO_CAPTURE", __FUNCTION__, devName); + return; + } + } + // See if we can initialize ExternalCameraDevice correctly + sp<device::V3_4::implementation::ExternalCameraDevice> deviceImpl = + new device::V3_4::implementation::ExternalCameraDevice(devName, mCfg); + if (deviceImpl == nullptr || deviceImpl->isInitFailed()) { + ALOGW("%s: Attempt to init camera device %s failed!", __FUNCTION__, devName); + return; + } + deviceImpl.clear(); + + addExternalCamera(devName); + return; +} + +void ExternalCameraProviderImpl_2_7::deviceRemoved(const char* devName) { + Mutex::Autolock _l(mLock); + std::string deviceName; + std::string cameraId = + std::to_string(mCfg.cameraIdOffset + std::atoi(devName + kDevicePrefixLen)); + if (mPreferredHal3MinorVersion == 6) { + deviceName = std::string("device@3.6/external/") + cameraId; + } else if (mPreferredHal3MinorVersion == 5) { + deviceName = std::string("device@3.5/external/") + cameraId; + } else { + deviceName = std::string("device@3.4/external/") + cameraId; + } + if (mCameraStatusMap.erase(deviceName) != 0) { + if (mCallbacks != nullptr) { + mCallbacks->cameraDeviceStatusChange(deviceName, CameraDeviceStatus::NOT_PRESENT); + } + } else { + ALOGE("%s: cannot find camera device %s", __FUNCTION__, devName); + } +} + +ExternalCameraProviderImpl_2_7::HotplugThread::HotplugThread(ExternalCameraProviderImpl_2_7* parent) + : Thread(/*canCallJava*/ false), + mParent(parent), + mInternalDevices(parent->mCfg.mInternalDevices) {} + +ExternalCameraProviderImpl_2_7::HotplugThread::~HotplugThread() {} + +bool ExternalCameraProviderImpl_2_7::HotplugThread::threadLoop() { + // Update existing cameras + mParent->updateAttachedCameras(); + + // Watch new video devices + mINotifyFD = inotify_init(); + if (mINotifyFD < 0) { + ALOGE("%s: inotify init failed! Exiting threadloop", __FUNCTION__); + return true; + } + + mWd = inotify_add_watch(mINotifyFD, kDevicePath, IN_CREATE | IN_DELETE); + if (mWd < 0) { + ALOGE("%s: inotify add watch failed! Exiting threadloop", __FUNCTION__); + return true; + } + + bool done = false; + char eventBuf[512]; + while (!done) { + int offset = 0; + int ret = read(mINotifyFD, eventBuf, sizeof(eventBuf)); + if (ret >= (int)sizeof(struct inotify_event)) { + while (offset < ret) { + struct inotify_event* event = (struct inotify_event*)&eventBuf[offset]; + if (event->wd == mWd) { + ALOGV("%s inotify_event %s", __FUNCTION__, event->name); + if (!strncmp(kPrefix, event->name, kPrefixLen)) { + std::string deviceId(event->name + kPrefixLen); + if (mInternalDevices.count(deviceId) == 0) { + char v4l2DevicePath[kMaxDevicePathLen]; + snprintf(v4l2DevicePath, kMaxDevicePathLen, "%s%s", kDevicePath, + event->name); + if (event->mask & IN_CREATE) { + mParent->deviceAdded(v4l2DevicePath); + } + if (event->mask & IN_DELETE) { + mParent->deviceRemoved(v4l2DevicePath); + } + } + } + } + offset += sizeof(struct inotify_event) + event->len; + } + } + } + + return true; +} + +Return<void> ExternalCameraProviderImpl_2_7::notifyDeviceStateChange( + hidl_bitfield<DeviceState> /*newState*/) { + return Void(); +} + +Return<void> ExternalCameraProviderImpl_2_7::getConcurrentStreamingCameraIds( + ICameraProvider::getConcurrentStreamingCameraIds_cb _hidl_cb) { + hidl_vec<hidl_vec<hidl_string>> hidl_camera_id_combinations; + _hidl_cb(Status::OK, hidl_camera_id_combinations); + return Void(); +} + +Return<void> ExternalCameraProviderImpl_2_7::isConcurrentStreamCombinationSupported( + const hidl_vec<::android::hardware::camera::provider::V2_6:: + CameraIdAndStreamCombination>& /* configs */, + ICameraProvider::isConcurrentStreamCombinationSupported_cb _hidl_cb) { + _hidl_cb(Status::OK, false); + return Void(); +} + +Return<void> ExternalCameraProviderImpl_2_7::isConcurrentStreamCombinationSupported_2_7( + const hidl_vec<CameraIdAndStreamCombination>& /* configs */, + ICameraProvider::isConcurrentStreamCombinationSupported_2_7_cb _hidl_cb) { + _hidl_cb(Status::OK, false); + return Void(); +} + +} // namespace implementation +} // namespace V2_7 +} // namespace provider +} // namespace camera +} // namespace hardware +} // namespace android diff --git a/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.h b/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.h new file mode 100644 index 0000000000..da9f6b3a91 --- /dev/null +++ b/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2021 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_CAMERA_PROVIDER_V2_7_EXTCAMERAPROVIDER_H +#define ANDROID_HARDWARE_CAMERA_PROVIDER_V2_7_EXTCAMERAPROVIDER_H + +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> +#include <utils/Mutex.h> +#include <utils/Thread.h> +#include <string> +#include <unordered_map> +#include <unordered_set> +#include "ExternalCameraUtils.h" + +#include <android/hardware/camera/provider/2.6/ICameraProviderCallback.h> +#include <android/hardware/camera/provider/2.7/ICameraProvider.h> + +namespace android { +namespace hardware { +namespace camera { +namespace provider { +namespace V2_7 { +namespace implementation { + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::camera::common::V1_0::CameraDeviceStatus; +using ::android::hardware::camera::common::V1_0::Status; +using ::android::hardware::camera::common::V1_0::VendorTagSection; +using ::android::hardware::camera::external::common::ExternalCameraConfig; +using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; +using ::android::hardware::camera::provider::V2_5::DeviceState; +using ::android::hardware::camera::provider::V2_7::CameraIdAndStreamCombination; +using ::android::hardware::camera::provider::V2_7::ICameraProvider; +using ::android::hidl::base::V1_0::IBase; + +/** + * The implementation of external webcam CameraProvider 2.7, separated + * from the HIDL interface layer to allow for implementation reuse by later + * provider versions. + * + * This camera provider supports standard UVC webcameras via the Linux V4L2 + * UVC driver. + */ +struct ExternalCameraProviderImpl_2_7 { + ExternalCameraProviderImpl_2_7(); + ~ExternalCameraProviderImpl_2_7(); + + // Caller must use this method to check if CameraProvider ctor failed + bool isInitFailed() { return false; } + + // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow. + Return<Status> setCallback(const sp<ICameraProviderCallback>& callback); + Return<void> getVendorTags(ICameraProvider::getVendorTags_cb _hidl_cb); + Return<void> getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb); + Return<void> isSetTorchModeSupported(ICameraProvider::isSetTorchModeSupported_cb _hidl_cb); + Return<void> getCameraDeviceInterface_V1_x(const hidl_string&, + ICameraProvider::getCameraDeviceInterface_V1_x_cb); + Return<void> getCameraDeviceInterface_V3_x(const hidl_string&, + ICameraProvider::getCameraDeviceInterface_V3_x_cb); + + // Methods from ::android::hardware::camera::provider::V2_5::ICameraProvider follow. + Return<void> notifyDeviceStateChange(hidl_bitfield<DeviceState> newState); + + // Methods from ::android::hardware::camera::provider::V2_7::ICameraProvider follow. + Return<void> getConcurrentStreamingCameraIds( + ICameraProvider::getConcurrentStreamingCameraIds_cb _hidl_cb); + + Return<void> isConcurrentStreamCombinationSupported( + const hidl_vec< + ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination>& + configs, + ICameraProvider::isConcurrentStreamCombinationSupported_cb _hidl_cb); + + Return<void> isConcurrentStreamCombinationSupported_2_7( + const hidl_vec<CameraIdAndStreamCombination>& configs, + ICameraProvider::isConcurrentStreamCombinationSupported_2_7_cb _hidl_cb); + + private: + void addExternalCamera(const char* devName); + + void deviceAdded(const char* devName); + + void deviceRemoved(const char* devName); + + void updateAttachedCameras(); + + class HotplugThread : public android::Thread { + public: + HotplugThread(ExternalCameraProviderImpl_2_7* parent); + ~HotplugThread(); + + virtual bool threadLoop() override; + + private: + ExternalCameraProviderImpl_2_7* mParent = nullptr; + const std::unordered_set<std::string> mInternalDevices; + + int mINotifyFD = -1; + int mWd = -1; + }; + + Mutex mLock; + sp<ICameraProviderCallback> mCallbacks = nullptr; + std::unordered_map<std::string, CameraDeviceStatus> mCameraStatusMap; // camera id -> status + const ExternalCameraConfig mCfg; + sp<HotplugThread> mHotPlugThread; + int mPreferredHal3MinorVersion; +}; + +} // namespace implementation +} // namespace V2_7 +} // namespace provider +} // namespace camera +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_PROVIDER_V2_7_EXTCAMERAPROVIDER_H diff --git a/camera/provider/2.7/default/android.hardware.camera.provider@2.7-external-service-lazy.rc b/camera/provider/2.7/default/android.hardware.camera.provider@2.7-external-service-lazy.rc new file mode 100644 index 0000000000..9292c4f959 --- /dev/null +++ b/camera/provider/2.7/default/android.hardware.camera.provider@2.7-external-service-lazy.rc @@ -0,0 +1,13 @@ +service vendor.camera-provider-2-7-ext /vendor/bin/hw/android.hardware.camera.provider@2.7-external-service-lazy + interface android.hardware.camera.provider@2.4::ICameraProvider external/0 + interface android.hardware.camera.provider@2.5::ICameraProvider external/0 + interface android.hardware.camera.provider@2.6::ICameraProvider external/0 + interface android.hardware.camera.provider@2.7::ICameraProvider external/0 + class hal + oneshot + disabled + user cameraserver + group audio camera input drmrpc usb + ioprio rt 4 + capabilities SYS_NICE + task_profiles CameraServiceCapacity MaxPerformance
\ No newline at end of file diff --git a/camera/provider/2.7/default/android.hardware.camera.provider@2.7-external-service.rc b/camera/provider/2.7/default/android.hardware.camera.provider@2.7-external-service.rc new file mode 100644 index 0000000000..2c9b782c1c --- /dev/null +++ b/camera/provider/2.7/default/android.hardware.camera.provider@2.7-external-service.rc @@ -0,0 +1,11 @@ +service vendor.camera-provider-2-7-ext /vendor/bin/hw/android.hardware.camera.provider@2.7-external-service + interface android.hardware.camera.provider@2.4::ICameraProvider external/0 + interface android.hardware.camera.provider@2.5::ICameraProvider external/0 + interface android.hardware.camera.provider@2.6::ICameraProvider external/0 + interface android.hardware.camera.provider@2.7::ICameraProvider external/0 + class hal + user cameraserver + group audio camera input drmrpc usb + ioprio rt 4 + capabilities SYS_NICE + task_profiles CameraServiceCapacity MaxPerformance diff --git a/camera/provider/2.7/default/external-service.cpp b/camera/provider/2.7/default/external-service.cpp new file mode 100644 index 0000000000..90b823970f --- /dev/null +++ b/camera/provider/2.7/default/external-service.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2021 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. + */ + +#ifdef LAZY_SERVICE +#define LOG_TAG "android.hardware.camera.provider@2.7-external-service-lazy" +#else +#define LOG_TAG "android.hardware.camera.provider@2.7-external-service" +#endif + +#include <android/hardware/camera/provider/2.7/ICameraProvider.h> +#include <binder/ProcessState.h> +#include <hidl/HidlLazyUtils.h> +#include <hidl/HidlTransportSupport.h> + +#include "CameraProvider_2_7.h" +#include "ExternalCameraProviderImpl_2_7.h" + +using android::status_t; +using android::hardware::camera::provider::V2_7::ICameraProvider; +using android::hidl::base::V1_0::IBase; + +#ifdef LAZY_SERVICE +const bool kLazyService = true; +#else +const bool kLazyService = false; +#endif + +int main() { + using namespace android::hardware::camera::provider::V2_7::implementation; + + ALOGI("CameraProvider@2.7 external webcam service is starting."); + + ::android::hardware::configureRpcThreadpool(/*threads*/ HWBINDER_THREAD_COUNT, + /*willJoin*/ true); + + ::android::sp<CameraProvider<ExternalCameraProviderImpl_2_7>> provider = + new CameraProvider<ExternalCameraProviderImpl_2_7>(); + + status_t status; + if (kLazyService) { + auto serviceRegistrar = ::android::hardware::LazyServiceRegistrar::getInstance(); + status = serviceRegistrar.registerService(provider, "external/0"); + } else { + status = provider->registerAsService("external/0"); + } + + LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering provider service: %d", + status); + + ::android::hardware::joinRpcThreadpool(); + + return 0; +}
\ No newline at end of file |