diff options
-rw-r--r-- | camera/Android.bp | 1 | ||||
-rw-r--r-- | camera/common/1.0/default/CameraModule.cpp | 34 | ||||
-rw-r--r-- | camera/common/1.0/default/include/CameraModule.h | 13 | ||||
-rw-r--r-- | camera/device/1.0/ICameraDevice.hal | 5 | ||||
-rw-r--r-- | camera/provider/2.4/ICameraProvider.hal | 24 | ||||
-rw-r--r-- | camera/provider/2.4/default/Android.bp | 23 | ||||
-rw-r--r-- | camera/provider/2.4/default/CameraProvider.cpp | 405 | ||||
-rw-r--r-- | camera/provider/2.4/default/CameraProvider.h | 119 |
8 files changed, 603 insertions, 21 deletions
diff --git a/camera/Android.bp b/camera/Android.bp index fb6de9ea06..c6a76fb1d7 100644 --- a/camera/Android.bp +++ b/camera/Android.bp @@ -7,4 +7,5 @@ subdirs = [ "device/3.2/default", "metadata/3.2", "provider/2.4", + "provider/2.4/default", ] diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp index d8a424ec17..5d9ae4d31a 100644 --- a/camera/common/1.0/default/CameraModule.cpp +++ b/camera/common/1.0/default/CameraModule.cpp @@ -344,7 +344,7 @@ int CameraModule::open(const char* id, struct hw_device_t** device) { return res; } -bool CameraModule::isOpenLegacyDefined() { +bool CameraModule::isOpenLegacyDefined() const { if (getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_3) { return false; } @@ -376,7 +376,7 @@ int CameraModule::setCallbacks(const camera_module_callbacks_t *callbacks) { return res; } -bool CameraModule::isVendorTagDefined() { +bool CameraModule::isVendorTagDefined() const { return mModule->get_vendor_tag_ops != NULL; } @@ -388,11 +388,25 @@ void CameraModule::getVendorTagOps(vendor_tag_ops_t* ops) { } } +bool CameraModule::isSetTorchModeSupported() const { + if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) { + if (mModule->set_torch_mode == NULL) { + ALOGE("%s: Module 2.4 device must support set torch API!", + __FUNCTION__); + return false; + } + return true; + } + return false; +} + int CameraModule::setTorchMode(const char* camera_id, bool enable) { - int res; - ATRACE_BEGIN("camera_module->set_torch_mode"); - res = mModule->set_torch_mode(camera_id, enable); - ATRACE_END(); + int res = INVALID_OPERATION; + if (mModule->set_torch_mode != NULL) { + ATRACE_BEGIN("camera_module->set_torch_mode"); + res = mModule->set_torch_mode(camera_id, enable); + ATRACE_END(); + } return res; } @@ -409,19 +423,19 @@ status_t CameraModule::filterOpenErrorCode(status_t err) { return -ENODEV; } -uint16_t CameraModule::getModuleApiVersion() { +uint16_t CameraModule::getModuleApiVersion() const { return mModule->common.module_api_version; } -const char* CameraModule::getModuleName() { +const char* CameraModule::getModuleName() const { return mModule->common.name; } -uint16_t CameraModule::getHalApiVersion() { +uint16_t CameraModule::getHalApiVersion() const { return mModule->common.hal_api_version; } -const char* CameraModule::getModuleAuthor() { +const char* CameraModule::getModuleAuthor() const { return mModule->common.author; } diff --git a/camera/common/1.0/default/include/CameraModule.h b/camera/common/1.0/default/include/CameraModule.h index 907c807992..68d4f9051c 100644 --- a/camera/common/1.0/default/include/CameraModule.h +++ b/camera/common/1.0/default/include/CameraModule.h @@ -49,16 +49,17 @@ public: int getDeviceVersion(int cameraId); int getNumberOfCameras(void); int open(const char* id, struct hw_device_t** device); - bool isOpenLegacyDefined(); + bool isOpenLegacyDefined() const; int openLegacy(const char* id, uint32_t halVersion, struct hw_device_t** device); int setCallbacks(const camera_module_callbacks_t *callbacks); - bool isVendorTagDefined(); + bool isVendorTagDefined() const; void getVendorTagOps(vendor_tag_ops_t* ops); + bool isSetTorchModeSupported() const; int setTorchMode(const char* camera_id, bool enable); - uint16_t getModuleApiVersion(); - const char* getModuleName(); - uint16_t getHalApiVersion(); - const char* getModuleAuthor(); + uint16_t getModuleApiVersion() const; + const char* getModuleName() const; + uint16_t getHalApiVersion() const; + const char* getModuleAuthor() const; // Only used by CameraModuleFixture native test. Do NOT use elsewhere. void *getDso(); diff --git a/camera/device/1.0/ICameraDevice.hal b/camera/device/1.0/ICameraDevice.hal index acca9a7b67..d232a672a7 100644 --- a/camera/device/1.0/ICameraDevice.hal +++ b/camera/device/1.0/ICameraDevice.hal @@ -78,11 +78,6 @@ interface ICameraDevice { */ getCameraInfo() generates (Status status, CameraInfo info); - // TODO: add query setTorch mode support so camera service can tell whether - // it needs to simulate torch or not (without calling setTorchMode - // which is visible to end user) - // Should this be put to device hal or provider hal? - /** * setTorchMode: * diff --git a/camera/provider/2.4/ICameraProvider.hal b/camera/provider/2.4/ICameraProvider.hal index 564167b75b..3015b7d9e1 100644 --- a/camera/provider/2.4/ICameraProvider.hal +++ b/camera/provider/2.4/ICameraProvider.hal @@ -120,6 +120,30 @@ interface ICameraProvider { generates (Status status, vec<string> cameraDeviceNames); /** + * isSetTorchModeSupported: + * + * Returns if the camera devices known to this camera provider support + * setTorchMode API or not. If the provider does not support setTorchMode + * API, calling to setTorchMode will return METHOD_NOT_SUPPORTED. + * + * Note that not every camera device has a flash unit, so even this API + * returns true, setTorchMode call might still fail due to the camera device + * does not have a flash unit. In such case, the returned status will be + * OPERATION_NOT_SUPPORTED. + * + * @return status Status code for the operation, one of: + * OK: + * On a succesful call + * INTERNAL_ERROR: + * Torch API support cannot be queried. This may be due to + * a failure to initialize the camera subsystem, for example. + * @return support Whether the camera devices known to this provider + * supports setTorchMode API or not. + * + */ + isSetTorchModeSupported() generates (Status status, bool support); + + /** * getCameraDeviceInterface_VN_x: * * Return a android.hardware.camera.device@N.x/ICameraDevice interface for diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp new file mode 100644 index 0000000000..f28c9cd757 --- /dev/null +++ b/camera/provider/2.4/default/Android.bp @@ -0,0 +1,23 @@ +cc_library_shared { + name: "android.hardware.camera.provider@2.4-impl", + relative_install_path: "hw", + srcs: ["CameraProvider.cpp"], + shared_libs: [ + "libhidlbase", + "libhidltransport", + "libhwbinder", + "libutils", + "libcutils", + "android.hardware.camera.device@1.0", + "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.2-impl", + "android.hardware.camera.provider@2.4", + "android.hardware.camera.common@1.0", + "liblog", + "libhardware", + "libcamera_metadata" + ], + static_libs: [ + "android.hardware.camera.common@1.0-helper" + ] +} diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp new file mode 100644 index 0000000000..d9ac26168e --- /dev/null +++ b/camera/provider/2.4/default/CameraProvider.cpp @@ -0,0 +1,405 @@ +/* + * Copyright (C) 2016 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 "CamProvider@2.4-impl" +#include <android/log.h> + +#include <regex> + +#include "CameraProvider.h" +#include "CameraDevice.h" +#include <string.h> +#include <utils/Trace.h> + + +namespace android { +namespace hardware { +namespace camera { +namespace provider { +namespace V2_4 { +namespace implementation { + +namespace { +const char *kLegacyProviderName = "legacy/0"; +// "device@<version>/legacy/<id>" +const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)"); +const char *kHAL3_2 = "3.2"; +const char *kHAL1_0 = "1.0"; +const int kMaxCameraDeviceNameLen = 128; +const int kMaxCameraIdLen = 16; + +} // anonymous namespace + +using ::android::hardware::camera::common::V1_0::CameraMetadataType; +using ::android::hardware::camera::common::V1_0::Status; + +/** + * static callback forwarding methods from HAL to instance + */ +void CameraProvider::sCameraDeviceStatusChange( + const struct camera_module_callbacks* callbacks, + int camera_id, + int new_status) { + ALOGI("%s++", __FUNCTION__); + sp<CameraProvider> cp = const_cast<CameraProvider*>( + static_cast<const CameraProvider*>(callbacks)); + + if (cp == nullptr) { + ALOGE("%s: callback ops is null", __FUNCTION__); + return; + } + + ALOGI("%s resolved provider %p", __FUNCTION__, cp.get()); + + Mutex::Autolock _l(cp->mCbLock); + char cameraId[kMaxCameraIdLen]; + snprintf(cameraId, sizeof(cameraId), "%d", camera_id); + std::string cameraIdStr(cameraId); + cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status; + if (cp->mCallbacks != nullptr) { + CameraDeviceStatus status = (CameraDeviceStatus) new_status; + for (auto const& deviceNamePair : cp->mCameraDeviceNames) { + if (cameraIdStr.compare(deviceNamePair.first) == 0) { + cp->mCallbacks->cameraDeviceStatusChange( + deviceNamePair.second, status); + } + } + } + ALOGI("%s--", __FUNCTION__); +} + +void CameraProvider::sTorchModeStatusChange( + const struct camera_module_callbacks* callbacks, + const char* camera_id, + int new_status) { + ALOGI("%s++", __FUNCTION__); + sp<CameraProvider> cp = const_cast<CameraProvider*>( + static_cast<const CameraProvider*>(callbacks)); + + if (cp == nullptr) { + ALOGE("%s: callback ops is null", __FUNCTION__); + return; + } + + ALOGI("%s resolved provider %p", __FUNCTION__, cp.get()); + + Mutex::Autolock _l(cp->mCbLock); + if (cp->mCallbacks != nullptr) { + std::string cameraIdStr(camera_id); + TorchModeStatus status = (TorchModeStatus) new_status; + for (auto const& deviceNamePair : cp->mCameraDeviceNames) { + if (cameraIdStr.compare(getLegacyCameraId(deviceNamePair.first)) == 0) { + cp->mCallbacks->torchModeStatusChange( + deviceNamePair.second, status); + } + } + } + ALOGI("%s--", __FUNCTION__); +} + +Status CameraProvider::getHidlStatus(int status) { + switch (status) { + case 0: return Status::OK; + case -ENODEV: return Status::INTERNAL_ERROR; + case -EINVAL: return Status::ILLEGAL_ARGUMENT; + default: + ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status); + return Status::INTERNAL_ERROR; + } +} + +bool CameraProvider::matchDeviceName(const hidl_string& deviceName, std::smatch& sm) { + std::string deviceNameStd(deviceName.c_str()); + return std::regex_match(deviceNameStd, sm, kDeviceNameRE); +} + +std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) { + std::smatch sm; + bool match = matchDeviceName(deviceName, sm); + if (!match) { + return std::string(""); + } + return sm[2]; +} + +int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) { + std::smatch sm; + bool match = matchDeviceName(deviceName, sm); + if (!match) { + return -1; + } + if (sm[1].compare(kHAL3_2) == 0) { + // maybe switched to 3.4 or define the hidl version enumlater + return CAMERA_DEVICE_API_VERSION_3_2; + } else if (sm[1].compare(kHAL1_0) == 0) { + return CAMERA_DEVICE_API_VERSION_1_0; + } + return 0; +} + +std::string CameraProvider::getHidlDeviceName( + std::string cameraId, int deviceVersion) { + // Maybe consider create a version check method and SortedVec to speed up? + if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 && + deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 && + deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 && + deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) { + return hidl_string(""); + } + const char* versionStr = (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) ? kHAL1_0 : kHAL3_2; + char deviceName[kMaxCameraDeviceNameLen]; + snprintf(deviceName, sizeof(deviceName), "device@%s/legacy/%s", + versionStr, cameraId.c_str()); + return deviceName; +} + +CameraProvider::CameraProvider() : + camera_module_callbacks_t({sCameraDeviceStatusChange, + sTorchModeStatusChange}) { + mInitFailed = initialize(); +} + +CameraProvider::~CameraProvider() {} + +bool CameraProvider::initialize() { + camera_module_t *rawModule; + int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, + (const hw_module_t **)&rawModule); + if (err < 0) { + ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err)); + return true; + } + + mModule = new CameraModule(rawModule); + err = mModule->init(); + if (err != OK) { + ALOGE("Could not initialize camera HAL module: %d (%s)", err, + strerror(-err)); + mModule.clear(); + return true; + } + ALOGI("Loaded \"%s\" camera module", mModule->getModuleName()); + + mNumberOfLegacyCameras = mModule->getNumberOfCameras(); + for (int i = 0; i < mNumberOfLegacyCameras; i++) { + char cameraId[kMaxCameraIdLen]; + snprintf(cameraId, sizeof(cameraId), "%d", i); + std::string cameraIdStr(cameraId); + mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT; + mCameraIds.add(cameraIdStr); + + // initialize mCameraDeviceNames and mOpenLegacySupported + mOpenLegacySupported[cameraIdStr] = false; + int deviceVersion = mModule->getDeviceVersion(i); + mCameraDeviceNames.add( + std::make_pair(cameraIdStr, + getHidlDeviceName(cameraIdStr, deviceVersion))); + if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 && + mModule->isOpenLegacyDefined()) { + // try open_legacy to see if it actually works + struct hw_device_t* halDev = nullptr; + int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev); + if (ret == 0) { + mOpenLegacySupported[cameraIdStr] = true; + halDev->close(halDev); + mCameraDeviceNames.add( + std::make_pair(cameraIdStr, + getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0))); + } else if (ret == -EBUSY || ret == -EUSERS) { + // Looks like this provider instance is not initialized during + // system startup and there are other camera users already. + // Not a good sign but not fatal. + ALOGW("%s: open_legacy try failed!", __FUNCTION__); + } + } + } + + // Setup vendor tags here so HAL can setup vendor keys in camera characteristics + VendorTagDescriptor::clearGlobalVendorTagDescriptor(); + setUpVendorTags(); + return false; +} + +bool CameraProvider::setUpVendorTags() { + ATRACE_CALL(); + vendor_tag_ops_t vOps = vendor_tag_ops_t(); + + // Check if vendor operations have been implemented + if (!mModule->isVendorTagDefined()) { + ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__); + return false; + } + + mModule->getVendorTagOps(&vOps); + + // Ensure all vendor operations are present + if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr || + vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr || + vOps.get_tag_type == nullptr) { + ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions." + , __FUNCTION__); + return false; + } + + // Read all vendor tag definitions into a descriptor + sp<VendorTagDescriptor> desc; + status_t res; + if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc)) + != OK) { + ALOGE("%s: Could not generate descriptor from vendor tag operations," + "received error %s (%d). Camera clients will not be able to use" + "vendor tags", __FUNCTION__, strerror(res), res); + return false; + } + + // Set the global descriptor to use with camera metadata + VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc); + const SortedVector<String8>* sectionNames = desc->getAllSectionNames(); + size_t numSections = sectionNames->size(); + std::vector<std::vector<VendorTag>> tagsBySection(numSections); + int tagCount = desc->getTagCount(); + std::vector<uint32_t> tags(tagCount); + desc->getTagArray(tags.data()); + for (int i = 0; i < tagCount; i++) { + VendorTag vt; + vt.tagId = tags[i]; + vt.tagName = desc->getTagName(tags[i]); + vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]); + ssize_t sectionIdx = desc->getSectionIndex(tags[i]); + tagsBySection[sectionIdx].push_back(vt); + } + mVendorTagSections.resize(numSections); + for (size_t s = 0; s < numSections; s++) { + mVendorTagSections[s].sectionName = (*sectionNames)[s].string(); + mVendorTagSections[s].tags = tagsBySection[s]; + } + return true; +} + +// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow. +Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) { + { + Mutex::Autolock _l(mCbLock); + mCallbacks = callback; + } // release lock here because HAL might send callbacks in setCallbacks call + return getHidlStatus(mModule->setCallbacks(this)); +} + +Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) { + _hidl_cb(Status::OK, mVendorTagSections); + return Void(); +} + +Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) { + std::vector<hidl_string> deviceNameList; + for (auto const& deviceNamePair : mCameraDeviceNames) { + if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) { + deviceNameList.push_back(deviceNamePair.second); + } + } + hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList); + _hidl_cb (Status::OK, hidlDeviceNameList); + return Void(); +} + +Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) { + bool support = mModule->isSetTorchModeSupported(); + _hidl_cb (Status::OK, support); + return Void(); +} + +Return<void> CameraProvider::getCameraDeviceInterface_V1_x(const hidl_string& /*cameraDeviceName*/, getCameraDeviceInterface_V1_x_cb /*_hidl_cb*/) { + // TODO implement after device 1.0 is implemented + return Void(); +} + +Return<void> CameraProvider::getCameraDeviceInterface_V3_x(const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) { + std::smatch sm; + bool match = matchDeviceName(cameraDeviceName, sm); + if (!match) { + _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); + return Void(); + } + + std::string cameraId = sm[2]; + std::string deviceName(cameraDeviceName.c_str()); + ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName)); + if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch + Status status = Status::OK; + ssize_t idx = mCameraIds.indexOf(cameraId); + if (idx == NAME_NOT_FOUND) { + status = Status::ILLEGAL_ARGUMENT; + } else { // invalid version + status = Status::OPERATION_NOT_SUPPORTED; + } + _hidl_cb(status, nullptr); + return Void(); + } + + if (mCameraStatusMap.count(cameraId) == 0 || + mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) { + _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); + return Void(); + } + + // TODO: we also need to keep a wp list of all generated devices to notify + // devices of device present status change, but then each device might + // need a sp<provider> to keep provider alive until all device closed? + // Problem: do we have external camera products to test this? + sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device = + new android::hardware::camera::device::V3_2::implementation::CameraDevice( + mModule, cameraId, mCameraDeviceNames); + + if (device == nullptr) { + ALOGE("%s: cannot allocate camera device!", __FUNCTION__); + _hidl_cb(Status::INTERNAL_ERROR, nullptr); + return Void(); + } + + if (device->isInitFailed()) { + ALOGE("%s: camera device init failed!", __FUNCTION__); + device = nullptr; + _hidl_cb(Status::INTERNAL_ERROR, nullptr); + return Void(); + } + + _hidl_cb (Status::OK, device); + return Void(); +} + +ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) { + if (strcmp(name, kLegacyProviderName) != 0) { + return nullptr; + } + CameraProvider* provider = new CameraProvider(); + if (provider == nullptr) { + ALOGE("%s: cannot allocate camera provider!", __FUNCTION__); + return nullptr; + } + if (provider->isInitFailed()) { + ALOGE("%s: camera provider init failed!", __FUNCTION__); + delete provider; + return nullptr; + } + return provider; +} + +} // namespace implementation +} // namespace V2_4 +} // namespace provider +} // namespace camera +} // namespace hardware +} // namespace android diff --git a/camera/provider/2.4/default/CameraProvider.h b/camera/provider/2.4/default/CameraProvider.h new file mode 100644 index 0000000000..79899d96cc --- /dev/null +++ b/camera/provider/2.4/default/CameraProvider.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2016 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_4_CAMERAPROVIDER_H +#define ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_CAMERAPROVIDER_H + +#include "hardware/camera_common.h" +#include "utils/Mutex.h" +#include "utils/SortedVector.h" +#include <android/hardware/camera/provider/2.4/ICameraProvider.h> +#include <hidl/Status.h> +#include <hidl/MQDescriptor.h> +#include "CameraModule.h" +#include "VendorTagDescriptor.h" + +namespace android { +namespace hardware { +namespace camera { +namespace provider { +namespace V2_4 { +namespace implementation { + +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::common::V1_0::helper::CameraModule; +using ::android::hardware::camera::common::V1_0::helper::VendorTagDescriptor; +using ::android::hardware::camera::provider::V2_4::ICameraProvider; +using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::sp; +using ::android::Mutex; + +struct CameraProvider : public ICameraProvider, public camera_module_callbacks_t { + CameraProvider(); + ~CameraProvider(); + + // Caller must use this method to check if CameraProvider ctor failed + bool isInitFailed() { return mInitFailed; } + + // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow. + Return<Status> setCallback(const sp<ICameraProviderCallback>& callback) override; + Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override; + Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override; + Return<void> isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) override; + Return<void> getCameraDeviceInterface_V1_x(const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb) override; + Return<void> getCameraDeviceInterface_V3_x(const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) override; + +private: + Mutex mCbLock; + sp<ICameraProviderCallback> mCallbacks = nullptr; + + sp<CameraModule> mModule; + + int mNumberOfLegacyCameras; + std::map<std::string, camera_device_status_t> mCameraStatusMap; // camera id -> status + std::map<std::string, bool> mOpenLegacySupported; // camera id -> open_legacy HAL1.0 supported + SortedVector<std::string> mCameraIds; // the "0"/"1" legacy camera Ids + // (cameraId string, hidl device name) pairs + SortedVector<std::pair<std::string, std::string>> mCameraDeviceNames; + + // Must be queried before using any APIs. + // APIs will only work when this returns true + bool mInitFailed; + bool initialize(); + + hidl_vec<VendorTagSection> mVendorTagSections; + bool setUpVendorTags(); + + // extract legacy camera ID/device version from a HIDL device name + static bool matchDeviceName(const hidl_string& deviceName, std::smatch& sm); + static std::string getLegacyCameraId(const hidl_string& deviceName); + static int getCameraDeviceVersion(const hidl_string& deviceName); + + // create HIDL device name from camera ID and device version + static std::string getHidlDeviceName(std::string cameraId, int deviceVersion); + + // convert conventional HAL status to HIDL Status + static Status getHidlStatus(int); + + // static callback forwarding methods + static void sCameraDeviceStatusChange( + const struct camera_module_callbacks* callbacks, + int camera_id, + int new_status); + static void sTorchModeStatusChange( + const struct camera_module_callbacks* callbacks, + const char* camera_id, + int new_status); +}; + +extern "C" ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name); + +} // namespace implementation +} // namespace V2_4 +} // namespace provider +} // namespace camera +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_CAMERAPROVIDER_H |