mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Camera: Add default camera provider 2.4
Supports legacy camera HAL modules; also exports ICameraDevice instances. Test: compile Bug: 30985004 Change-Id: I2b9624a412de95dd43979a5e6650b170010c577a
This commit is contained in:
@@ -7,4 +7,5 @@ subdirs = [
|
||||
"device/3.2/default",
|
||||
"metadata/3.2",
|
||||
"provider/2.4",
|
||||
"provider/2.4/default",
|
||||
]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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:
|
||||
*
|
||||
|
||||
@@ -119,6 +119,30 @@ interface ICameraProvider {
|
||||
getCameraIdList()
|
||||
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:
|
||||
*
|
||||
|
||||
23
camera/provider/2.4/default/Android.bp
Normal file
23
camera/provider/2.4/default/Android.bp
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
405
camera/provider/2.4/default/CameraProvider.cpp
Normal file
405
camera/provider/2.4/default/CameraProvider.cpp
Normal file
@@ -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
|
||||
119
camera/provider/2.4/default/CameraProvider.h
Normal file
119
camera/provider/2.4/default/CameraProvider.h
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user