Camera: Support lazy HALs

Drop camera HAL references when unused.

Use ro.camera.enableLazyHal property to toggle behavior on or off.
 * If true, the cameraserver drops references to ICameraProvider HALs
   when they are not being used for either camera or torch.
 * If false (or unset), stores a strong reference to each ICameraProvider
   that is registered. This is the same as the old behavior.

Bug: 79374634
Test: Apply CL that lets camera HAL exit when unused. Open camera/enable
      torch, close camera/disable torch, check ps -A to see if HAL exits.
Change-Id: I1842f9bf9e862ab74e4ec8aa72fc46fc47782ed0
gugelfrei
Peter Kalauskas 6 years ago
parent b7bd4383c9
commit a29c135cab

@ -2215,6 +2215,8 @@ binder::Status CameraService::BasicClient::disconnect() {
sCameraService->removeByClient(this); sCameraService->removeByClient(this);
sCameraService->logDisconnected(mCameraIdStr, mClientPid, sCameraService->logDisconnected(mCameraIdStr, mClientPid,
String8(mClientPackageName)); String8(mClientPackageName));
sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
mCameraIdStr.c_str());
sp<IBinder> remote = getRemote(); sp<IBinder> remote = getRemote();
if (remote != nullptr) { if (remote != nullptr) {

@ -24,23 +24,37 @@
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
#include <future>
#include <inttypes.h> #include <inttypes.h>
#include <hardware/camera_common.h> #include <hardware/camera_common.h>
#include <hidl/ServiceManagement.h> #include <hidl/ServiceManagement.h>
#include <functional> #include <functional>
#include <camera_metadata_hidden.h> #include <camera_metadata_hidden.h>
#include <android-base/parseint.h> #include <android-base/parseint.h>
#include <android-base/logging.h>
#include <cutils/properties.h>
#include <hwbinder/IPCThreadState.h>
#include <utils/Trace.h>
namespace android { namespace android {
using namespace ::android::hardware::camera; using namespace ::android::hardware::camera;
using namespace ::android::hardware::camera::common::V1_0; using namespace ::android::hardware::camera::common::V1_0;
using std::literals::chrono_literals::operator""s;
namespace { namespace {
// Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the // Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the
// service manager // service manager
const std::string kLegacyProviderName("legacy/0"); const std::string kLegacyProviderName("legacy/0");
const std::string kExternalProviderName("external/0"); const std::string kExternalProviderName("external/0");
const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
// The extra amount of time to hold a reference to an ICameraProvider after it is no longer needed.
// Hold the reference for this extra time so that if the camera is unreferenced and then referenced
// again quickly, we do not let the HAL exit and then need to immediately restart it. An example
// when this could happen is switching from a front-facing to a rear-facing camera. If the HAL were
// to exit during the camera switch, the camera could appear janky to the user.
const std::chrono::system_clock::duration kCameraKeepAliveDelay = 3s;
} // anonymous namespace } // anonymous namespace
@ -74,6 +88,8 @@ status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListe
addProviderLocked(kLegacyProviderName, /*expected*/ false); addProviderLocked(kLegacyProviderName, /*expected*/ false);
addProviderLocked(kExternalProviderName, /*expected*/ false); addProviderLocked(kExternalProviderName, /*expected*/ false);
IPCThreadState::self()->flushCommands();
return OK; return OK;
} }
@ -219,26 +235,15 @@ status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id
return OK; return OK;
} }
bool CameraProviderManager::supportSetTorchMode(const std::string &id) { bool CameraProviderManager::supportSetTorchMode(const std::string &id) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex); std::lock_guard<std::mutex> lock(mInterfaceMutex);
bool support = false;
for (auto& provider : mProviders) { for (auto& provider : mProviders) {
auto deviceInfo = findDeviceInfoLocked(id); auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo != nullptr) { if (deviceInfo != nullptr) {
auto ret = provider->mInterface->isSetTorchModeSupported( return provider->mSetTorchModeSupported;
[&support](auto status, bool supported) {
if (status == Status::OK) {
support = supported;
}
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error checking torch mode support '%s': %s",
__FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
}
break;
} }
} }
return support; return false;
} }
status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) { status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
@ -247,6 +252,15 @@ status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled
auto deviceInfo = findDeviceInfoLocked(id); auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo == nullptr) return NAME_NOT_FOUND; if (deviceInfo == nullptr) return NAME_NOT_FOUND;
// Pass the camera ID to start interface so that it will save it to the map of ICameraProviders
// that are currently in use.
const sp<provider::V2_4::ICameraProvider> interface =
deviceInfo->mParentProvider->startProviderInterface();
if (interface == nullptr) {
return DEAD_OBJECT;
}
saveRef(DeviceMode::TORCH, deviceInfo->mId, interface);
return deviceInfo->setTorchMode(enabled); return deviceInfo->setTorchMode(enabled);
} }
@ -274,10 +288,22 @@ status_t CameraProviderManager::openSession(const std::string &id,
if (deviceInfo == nullptr) return NAME_NOT_FOUND; if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo); auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
const sp<provider::V2_4::ICameraProvider> provider =
deviceInfo->mParentProvider->startProviderInterface();
if (provider == nullptr) {
return DEAD_OBJECT;
}
saveRef(DeviceMode::CAMERA, id, provider);
Status status; Status status;
hardware::Return<void> ret; hardware::Return<void> ret;
ret = deviceInfo3->mInterface->open(callback, [&status, &session] auto interface = deviceInfo3->startDeviceInterface<
CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
if (interface == nullptr) {
return DEAD_OBJECT;
}
ret = interface->open(callback, [&status, &session]
(Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) { (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
status = s; status = s;
if (status == Status::OK) { if (status == Status::OK) {
@ -285,6 +311,7 @@ status_t CameraProviderManager::openSession(const std::string &id,
} }
}); });
if (!ret.isOk()) { if (!ret.isOk()) {
removeRef(DeviceMode::CAMERA, id);
ALOGE("%s: Transaction error opening a session for camera device %s: %s", ALOGE("%s: Transaction error opening a session for camera device %s: %s",
__FUNCTION__, id.c_str(), ret.description().c_str()); __FUNCTION__, id.c_str(), ret.description().c_str());
return DEAD_OBJECT; return DEAD_OBJECT;
@ -304,19 +331,82 @@ status_t CameraProviderManager::openSession(const std::string &id,
if (deviceInfo == nullptr) return NAME_NOT_FOUND; if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo); auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
const sp<provider::V2_4::ICameraProvider> provider =
deviceInfo->mParentProvider->startProviderInterface();
if (provider == nullptr) {
return DEAD_OBJECT;
}
saveRef(DeviceMode::CAMERA, id, provider);
hardware::Return<Status> status = deviceInfo1->mInterface->open(callback); auto interface = deviceInfo1->startDeviceInterface<
CameraProviderManager::ProviderInfo::DeviceInfo1::InterfaceT>();
if (interface == nullptr) {
return DEAD_OBJECT;
}
hardware::Return<Status> status = interface->open(callback);
if (!status.isOk()) { if (!status.isOk()) {
removeRef(DeviceMode::CAMERA, id);
ALOGE("%s: Transaction error opening a session for camera device %s: %s", ALOGE("%s: Transaction error opening a session for camera device %s: %s",
__FUNCTION__, id.c_str(), status.description().c_str()); __FUNCTION__, id.c_str(), status.description().c_str());
return DEAD_OBJECT; return DEAD_OBJECT;
} }
if (status == Status::OK) { if (status == Status::OK) {
*session = deviceInfo1->mInterface; *session = interface;
} }
return mapToStatusT(status); return mapToStatusT(status);
} }
void CameraProviderManager::saveRef(DeviceMode usageType, const std::string &cameraId,
sp<provider::V2_4::ICameraProvider> provider) {
if (!kEnableLazyHal) {
return;
}
ALOGI("Saving camera provider %s for camera device %s", provider->descriptor, cameraId.c_str());
std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
std::unordered_map<std::string, sp<provider::V2_4::ICameraProvider>> *primaryMap, *alternateMap;
if (usageType == DeviceMode::TORCH) {
primaryMap = &mTorchProviderByCameraId;
alternateMap = &mCameraProviderByCameraId;
} else {
primaryMap = &mCameraProviderByCameraId;
alternateMap = &mTorchProviderByCameraId;
}
auto id = cameraId.c_str();
(*primaryMap)[id] = provider;
auto search = alternateMap->find(id);
if (search != alternateMap->end()) {
ALOGW("%s: Camera device %s is using both torch mode and camera mode simultaneously. "
"That should not be possible", __FUNCTION__, id);
}
ALOGV("%s: Camera device %s connected", __FUNCTION__, id);
}
void CameraProviderManager::removeRef(DeviceMode usageType, const std::string &cameraId) {
if (!kEnableLazyHal) {
return;
}
ALOGI("Removing camera device %s", cameraId.c_str());
std::unordered_map<std::string, sp<provider::V2_4::ICameraProvider>> *providerMap;
if (usageType == DeviceMode::TORCH) {
providerMap = &mTorchProviderByCameraId;
} else {
providerMap = &mCameraProviderByCameraId;
}
std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
auto search = providerMap->find(cameraId.c_str());
if (search != providerMap->end()) {
auto ptr = search->second;
auto future = std::async(std::launch::async, [ptr] {
std::this_thread::sleep_for(kCameraKeepAliveDelay);
IPCThreadState::self()->flushCommands();
});
providerMap->erase(cameraId.c_str());
} else {
ALOGE("%s: Asked to remove reference for camera %s, but no reference to it was found. This "
"could mean removeRef was called twice for the same camera ID.", __FUNCTION__,
cameraId.c_str());
}
}
hardware::Return<void> CameraProviderManager::onRegistration( hardware::Return<void> CameraProviderManager::onRegistration(
const hardware::hidl_string& /*fqName*/, const hardware::hidl_string& /*fqName*/,
@ -334,6 +424,8 @@ hardware::Return<void> CameraProviderManager::onRegistration(
listener->onNewProviderRegistered(); listener->onNewProviderRegistered();
} }
IPCThreadState::self()->flushCommands();
return hardware::Return<void>(); return hardware::Return<void>();
} }
@ -581,9 +673,8 @@ status_t CameraProviderManager::addProviderLocked(const std::string& newProvider
} }
} }
sp<ProviderInfo> providerInfo = sp<ProviderInfo> providerInfo = new ProviderInfo(newProvider, this);
new ProviderInfo(newProvider, interface, this); status_t res = providerInfo->initialize(interface);
status_t res = providerInfo->initialize();
if (res != OK) { if (res != OK) {
return res; return res;
} }
@ -635,27 +726,26 @@ sp<CameraProviderManager::StatusListener> CameraProviderManager::getStatusListen
CameraProviderManager::ProviderInfo::ProviderInfo( CameraProviderManager::ProviderInfo::ProviderInfo(
const std::string &providerName, const std::string &providerName,
sp<provider::V2_4::ICameraProvider>& interface,
CameraProviderManager *manager) : CameraProviderManager *manager) :
mProviderName(providerName), mProviderName(providerName),
mInterface(interface),
mProviderTagid(generateVendorTagId(providerName)), mProviderTagid(generateVendorTagId(providerName)),
mUniqueDeviceCount(0), mUniqueDeviceCount(0),
mManager(manager) { mManager(manager) {
(void) mManager; (void) mManager;
} }
status_t CameraProviderManager::ProviderInfo::initialize() { status_t CameraProviderManager::ProviderInfo::initialize(
sp<provider::V2_4::ICameraProvider>& interface) {
status_t res = parseProviderName(mProviderName, &mType, &mId); status_t res = parseProviderName(mProviderName, &mType, &mId);
if (res != OK) { if (res != OK) {
ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__); ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
return BAD_VALUE; return BAD_VALUE;
} }
ALOGI("Connecting to new camera provider: %s, isRemote? %d", ALOGI("Connecting to new camera provider: %s, isRemote? %d",
mProviderName.c_str(), mInterface->isRemote()); mProviderName.c_str(), interface->isRemote());
// cameraDeviceStatusChange callbacks may be called (and causing new devices added) // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
// before setCallback returns // before setCallback returns
hardware::Return<Status> status = mInterface->setCallback(this); hardware::Return<Status> status = interface->setCallback(this);
if (!status.isOk()) { if (!status.isOk()) {
ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s", ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
__FUNCTION__, mProviderName.c_str(), status.description().c_str()); __FUNCTION__, mProviderName.c_str(), status.description().c_str());
@ -667,7 +757,7 @@ status_t CameraProviderManager::ProviderInfo::initialize() {
return mapToStatusT(status); return mapToStatusT(status);
} }
hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId); hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
if (!linked.isOk()) { if (!linked.isOk()) {
ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s", ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
__FUNCTION__, mProviderName.c_str(), linked.description().c_str()); __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
@ -679,7 +769,7 @@ status_t CameraProviderManager::ProviderInfo::initialize() {
// Get initial list of camera devices, if any // Get initial list of camera devices, if any
std::vector<std::string> devices; std::vector<std::string> devices;
hardware::Return<void> ret = mInterface->getCameraIdList([&status, this, &devices]( hardware::Return<void> ret = interface->getCameraIdList([&status, this, &devices](
Status idStatus, Status idStatus,
const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) { const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
status = idStatus; status = idStatus;
@ -708,6 +798,20 @@ status_t CameraProviderManager::ProviderInfo::initialize() {
return mapToStatusT(status); return mapToStatusT(status);
} }
ret = interface->isSetTorchModeSupported(
[this](auto status, bool supported) {
if (status == Status::OK) {
mSetTorchModeSupported = supported;
}
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error checking torch mode support '%s': %s",
__FUNCTION__, mProviderName.c_str(), ret.description().c_str());
return DEAD_OBJECT;
}
mIsRemote = interface->isRemote();
sp<StatusListener> listener = mManager->getStatusListener(); sp<StatusListener> listener = mManager->getStatusListener();
for (auto& device : devices) { for (auto& device : devices) {
std::string id; std::string id;
@ -730,9 +834,42 @@ status_t CameraProviderManager::ProviderInfo::initialize() {
mProviderName.c_str(), mDevices.size()); mProviderName.c_str(), mDevices.size());
mInitialized = true; mInitialized = true;
if (!kEnableLazyHal) {
// Save HAL reference indefinitely
mSavedInterface = interface;
}
return OK; return OK;
} }
const sp<provider::V2_4::ICameraProvider>
CameraProviderManager::ProviderInfo::startProviderInterface() {
ATRACE_CALL();
ALOGI("Request to start camera provider: %s", mProviderName.c_str());
if (mSavedInterface != nullptr) {
return mSavedInterface;
}
auto interface = mActiveInterface.promote();
if (interface == nullptr) {
ALOGI("Could not promote, calling getService(%s)", mProviderName.c_str());
interface = mManager->mServiceProxy->getService(mProviderName);
interface->setCallback(this);
hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
if (!linked.isOk()) {
ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
__FUNCTION__, mProviderName.c_str(), linked.description().c_str());
mManager->removeProvider(mProviderName);
return nullptr;
} else if (!linked) {
ALOGW("%s: Unable to link to provider '%s' death notifications",
__FUNCTION__, mProviderName.c_str());
}
mActiveInterface = interface;
} else {
ALOGI("Camera provider (%s) already in use. Re-using instance.", mProviderName.c_str());
}
return interface;
}
const std::string& CameraProviderManager::ProviderInfo::getType() const { const std::string& CameraProviderManager::ProviderInfo::getType() const {
return mType; return mType;
} }
@ -814,7 +951,7 @@ void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const { status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n", dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough", mProviderName.c_str(), mIsRemote ? "remote" : "passthrough",
mDevices.size()); mDevices.size());
for (auto& device : mDevices) { for (auto& device : mDevices) {
@ -942,6 +1079,9 @@ hardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChang
torchStatusToString(newStatus)); torchStatusToString(newStatus));
id = deviceInfo->mId; id = deviceInfo->mId;
known = true; known = true;
if (TorchModeStatus::AVAILABLE_ON != newStatus) {
mManager->removeRef(DeviceMode::TORCH, id);
}
break; break;
} }
} }
@ -977,7 +1117,11 @@ status_t CameraProviderManager::ProviderInfo::setUpVendorTags() {
hardware::hidl_vec<VendorTagSection> vts; hardware::hidl_vec<VendorTagSection> vts;
Status status; Status status;
hardware::Return<void> ret; hardware::Return<void> ret;
ret = mInterface->getVendorTags( const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
if (interface == nullptr) {
return DEAD_OBJECT;
}
ret = interface->getVendorTags(
[&](auto s, const auto& vendorTagSecs) { [&](auto s, const auto& vendorTagSecs) {
status = s; status = s;
if (s == Status::OK) { if (s == Status::OK) {
@ -1010,11 +1154,11 @@ template<class DeviceInfoT>
std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo> std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
CameraProviderManager::ProviderInfo::initializeDeviceInfo( CameraProviderManager::ProviderInfo::initializeDeviceInfo(
const std::string &name, const metadata_vendor_id_t tagId, const std::string &name, const metadata_vendor_id_t tagId,
const std::string &id, uint16_t minorVersion) const { const std::string &id, uint16_t minorVersion) {
Status status; Status status;
auto cameraInterface = auto cameraInterface =
getDeviceInterface<typename DeviceInfoT::InterfaceT>(name); startDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
if (cameraInterface == nullptr) return nullptr; if (cameraInterface == nullptr) return nullptr;
CameraResourceCost resourceCost; CameraResourceCost resourceCost;
@ -1041,13 +1185,13 @@ std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
} }
return std::unique_ptr<DeviceInfo>( return std::unique_ptr<DeviceInfo>(
new DeviceInfoT(name, tagId, id, minorVersion, resourceCost, new DeviceInfoT(name, tagId, id, minorVersion, resourceCost, this,
mProviderPublicCameraIds, cameraInterface)); mProviderPublicCameraIds, cameraInterface));
} }
template<class InterfaceT> template<class InterfaceT>
sp<InterfaceT> sp<InterfaceT>
CameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name) const { CameraProviderManager::ProviderInfo::startDeviceInterface(const std::string &name) {
ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__, ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
name.c_str(), InterfaceT::version.get_major()); name.c_str(), InterfaceT::version.get_major());
return nullptr; return nullptr;
@ -1055,12 +1199,16 @@ CameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name)
template<> template<>
sp<device::V1_0::ICameraDevice> sp<device::V1_0::ICameraDevice>
CameraProviderManager::ProviderInfo::getDeviceInterface CameraProviderManager::ProviderInfo::startDeviceInterface
<device::V1_0::ICameraDevice>(const std::string &name) const { <device::V1_0::ICameraDevice>(const std::string &name) {
Status status; Status status;
sp<device::V1_0::ICameraDevice> cameraInterface; sp<device::V1_0::ICameraDevice> cameraInterface;
hardware::Return<void> ret; hardware::Return<void> ret;
ret = mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface]( const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
if (interface == nullptr) {
return nullptr;
}
ret = interface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
Status s, sp<device::V1_0::ICameraDevice> interface) { Status s, sp<device::V1_0::ICameraDevice> interface) {
status = s; status = s;
cameraInterface = interface; cameraInterface = interface;
@ -1080,12 +1228,16 @@ CameraProviderManager::ProviderInfo::getDeviceInterface
template<> template<>
sp<device::V3_2::ICameraDevice> sp<device::V3_2::ICameraDevice>
CameraProviderManager::ProviderInfo::getDeviceInterface CameraProviderManager::ProviderInfo::startDeviceInterface
<device::V3_2::ICameraDevice>(const std::string &name) const { <device::V3_2::ICameraDevice>(const std::string &name) {
Status status; Status status;
sp<device::V3_2::ICameraDevice> cameraInterface; sp<device::V3_2::ICameraDevice> cameraInterface;
hardware::Return<void> ret; hardware::Return<void> ret;
ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface]( const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
if (interface == nullptr) {
return nullptr;
}
ret = interface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
Status s, sp<device::V3_2::ICameraDevice> interface) { Status s, sp<device::V3_2::ICameraDevice> interface) {
status = s; status = s;
cameraInterface = interface; cameraInterface = interface;
@ -1105,6 +1257,18 @@ CameraProviderManager::ProviderInfo::getDeviceInterface
CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {} CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
template<class InterfaceT>
sp<InterfaceT> CameraProviderManager::ProviderInfo::DeviceInfo::startDeviceInterface() {
sp<InterfaceT> device;
ATRACE_CALL();
if (mSavedInterface == nullptr) {
device = mParentProvider->startDeviceInterface<InterfaceT>(mName);
} else {
device = (InterfaceT *) mSavedInterface.get();
}
return device;
}
template<class InterfaceT> template<class InterfaceT>
status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface, status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
bool enabled) { bool enabled) {
@ -1116,31 +1280,31 @@ CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string&
const metadata_vendor_id_t tagId, const std::string &id, const metadata_vendor_id_t tagId, const std::string &id,
uint16_t minorVersion, uint16_t minorVersion,
const CameraResourceCost& resourceCost, const CameraResourceCost& resourceCost,
sp<ProviderInfo> parentProvider,
const std::vector<std::string>& publicCameraIds, const std::vector<std::string>& publicCameraIds,
sp<InterfaceT> interface) : sp<InterfaceT> interface) :
DeviceInfo(name, tagId, id, hardware::hidl_version{1, minorVersion}, DeviceInfo(name, tagId, id, hardware::hidl_version{1, minorVersion},
publicCameraIds, resourceCost), publicCameraIds, resourceCost, parentProvider) {
mInterface(interface) {
// Get default parameters and initialize flash unit availability // Get default parameters and initialize flash unit availability
// Requires powering on the camera device // Requires powering on the camera device
hardware::Return<Status> status = mInterface->open(nullptr); hardware::Return<Status> status = interface->open(nullptr);
if (!status.isOk()) { if (!status.isOk()) {
ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s", ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s",
__FUNCTION__, mId.c_str(), status.description().c_str()); __FUNCTION__, id.c_str(), status.description().c_str());
return; return;
} }
if (status != Status::OK) { if (status != Status::OK) {
ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__, ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__,
mId.c_str(), CameraProviderManager::statusToString(status)); id.c_str(), CameraProviderManager::statusToString(status));
return; return;
} }
hardware::Return<void> ret; hardware::Return<void> ret;
ret = mInterface->getParameters([this](const hardware::hidl_string& parms) { ret = interface->getParameters([this](const hardware::hidl_string& parms) {
mDefaultParameters.unflatten(String8(parms.c_str())); mDefaultParameters.unflatten(String8(parms.c_str()));
}); });
if (!ret.isOk()) { if (!ret.isOk()) {
ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s", ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s",
__FUNCTION__, mId.c_str(), status.description().c_str()); __FUNCTION__, id.c_str(), status.description().c_str());
return; return;
} }
const char *flashMode = const char *flashMode =
@ -1149,27 +1313,43 @@ CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string&
mHasFlashUnit = true; mHasFlashUnit = true;
} }
ret = mInterface->close(); status_t res = cacheCameraInfo(interface);
if (res != OK) {
ALOGE("%s: Could not cache CameraInfo", __FUNCTION__);
return;
}
ret = interface->close();
if (!ret.isOk()) { if (!ret.isOk()) {
ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s", ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s",
__FUNCTION__, mId.c_str(), status.description().c_str()); __FUNCTION__, id.c_str(), status.description().c_str());
}
if (!kEnableLazyHal) {
// Save HAL reference indefinitely
mSavedInterface = interface;
} }
} }
CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {} CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) { status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
return DeviceInfo::setTorchMode(mInterface, enabled); return setTorchModeForDevice<InterfaceT>(enabled);
} }
status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo( status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
hardware::CameraInfo *info) const { hardware::CameraInfo *info) const {
if (info == nullptr) return BAD_VALUE; if (info == nullptr) return BAD_VALUE;
*info = mInfo;
return OK;
}
status_t CameraProviderManager::ProviderInfo::DeviceInfo1::cacheCameraInfo(
sp<CameraProviderManager::ProviderInfo::DeviceInfo1::InterfaceT> interface) {
Status status; Status status;
device::V1_0::CameraInfo cInfo; device::V1_0::CameraInfo cInfo;
hardware::Return<void> ret; hardware::Return<void> ret;
ret = mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) { ret = interface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
status = s; status = s;
cInfo = camInfo; cInfo = camInfo;
}); });
@ -1184,27 +1364,31 @@ status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
switch(cInfo.facing) { switch(cInfo.facing) {
case device::V1_0::CameraFacing::BACK: case device::V1_0::CameraFacing::BACK:
info->facing = hardware::CAMERA_FACING_BACK; mInfo.facing = hardware::CAMERA_FACING_BACK;
break; break;
case device::V1_0::CameraFacing::EXTERNAL: case device::V1_0::CameraFacing::EXTERNAL:
// Map external to front for legacy API // Map external to front for legacy API
case device::V1_0::CameraFacing::FRONT: case device::V1_0::CameraFacing::FRONT:
info->facing = hardware::CAMERA_FACING_FRONT; mInfo.facing = hardware::CAMERA_FACING_FRONT;
break; break;
default: default:
ALOGW("%s: Device %s: Unknown camera facing: %d", ALOGW("%s: Device %s: Unknown camera facing: %d",
__FUNCTION__, mId.c_str(), cInfo.facing); __FUNCTION__, mId.c_str(), cInfo.facing);
info->facing = hardware::CAMERA_FACING_BACK; mInfo.facing = hardware::CAMERA_FACING_BACK;
} }
info->orientation = cInfo.orientation; mInfo.orientation = cInfo.orientation;
return OK; return OK;
} }
status_t CameraProviderManager::ProviderInfo::DeviceInfo1::dumpState(int fd) const { status_t CameraProviderManager::ProviderInfo::DeviceInfo1::dumpState(int fd) {
native_handle_t* handle = native_handle_create(1,0); native_handle_t* handle = native_handle_create(1,0);
handle->data[0] = fd; handle->data[0] = fd;
hardware::Return<Status> s = mInterface->dumpState(handle); const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
if (interface == nullptr) {
return DEAD_OBJECT;
}
hardware::Return<Status> s = interface->dumpState(handle);
native_handle_delete(handle); native_handle_delete(handle);
if (!s.isOk()) { if (!s.isOk()) {
return INVALID_OPERATION; return INVALID_OPERATION;
@ -1216,15 +1400,15 @@ CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string&
const metadata_vendor_id_t tagId, const std::string &id, const metadata_vendor_id_t tagId, const std::string &id,
uint16_t minorVersion, uint16_t minorVersion,
const CameraResourceCost& resourceCost, const CameraResourceCost& resourceCost,
sp<ProviderInfo> parentProvider,
const std::vector<std::string>& publicCameraIds, const std::vector<std::string>& publicCameraIds,
sp<InterfaceT> interface) : sp<InterfaceT> interface) :
DeviceInfo(name, tagId, id, hardware::hidl_version{3, minorVersion}, DeviceInfo(name, tagId, id, hardware::hidl_version{3, minorVersion},
publicCameraIds, resourceCost), publicCameraIds, resourceCost, parentProvider) {
mInterface(interface) {
// Get camera characteristics and initialize flash unit availability // Get camera characteristics and initialize flash unit availability
Status status; Status status;
hardware::Return<void> ret; hardware::Return<void> ret;
ret = mInterface->getCameraCharacteristics([&status, this](Status s, ret = interface->getCameraCharacteristics([&status, this](Status s,
device::V3_2::CameraMetadata metadata) { device::V3_2::CameraMetadata metadata) {
status = s; status = s;
if (s == Status::OK) { if (s == Status::OK) {
@ -1243,13 +1427,13 @@ CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string&
}); });
if (!ret.isOk()) { if (!ret.isOk()) {
ALOGE("%s: Transaction error getting camera characteristics for device %s" ALOGE("%s: Transaction error getting camera characteristics for device %s"
" to check for a flash unit: %s", __FUNCTION__, mId.c_str(), " to check for a flash unit: %s", __FUNCTION__, id.c_str(),
ret.description().c_str()); ret.description().c_str());
return; return;
} }
if (status != Status::OK) { if (status != Status::OK) {
ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)", ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
__FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status); __FUNCTION__, id.c_str(), CameraProviderManager::statusToString(status), status);
return; return;
} }
status_t res = fixupMonochromeTags(); status_t res = fixupMonochromeTags();
@ -1269,7 +1453,7 @@ CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string&
queryPhysicalCameraIds(); queryPhysicalCameraIds();
// Get physical camera characteristics if applicable // Get physical camera characteristics if applicable
auto castResult = device::V3_5::ICameraDevice::castFrom(mInterface); auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
if (!castResult.isOk()) { if (!castResult.isOk()) {
ALOGV("%s: Unable to convert ICameraDevice instance to version 3.5", __FUNCTION__); ALOGV("%s: Unable to convert ICameraDevice instance to version 3.5", __FUNCTION__);
return; return;
@ -1308,7 +1492,7 @@ CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string&
if (!ret.isOk()) { if (!ret.isOk()) {
ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s", ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s",
__FUNCTION__, id.c_str(), mId.c_str(), ret.description().c_str()); __FUNCTION__, id.c_str(), id.c_str(), ret.description().c_str());
return; return;
} }
if (status != Status::OK) { if (status != Status::OK) {
@ -1319,12 +1503,17 @@ CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string&
} }
} }
} }
if (!kEnableLazyHal) {
// Save HAL reference indefinitely
mSavedInterface = interface;
}
} }
CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {} CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) { status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
return DeviceInfo::setTorchMode(mInterface, enabled); return setTorchModeForDevice<InterfaceT>(enabled);
} }
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo( status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
@ -1375,10 +1564,14 @@ bool CameraProviderManager::ProviderInfo::DeviceInfo3::isAPI1Compatible() const
return isBackwardCompatible; return isBackwardCompatible;
} }
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::dumpState(int fd) const { status_t CameraProviderManager::ProviderInfo::DeviceInfo3::dumpState(int fd) {
native_handle_t* handle = native_handle_create(1,0); native_handle_t* handle = native_handle_create(1,0);
handle->data[0] = fd; handle->data[0] = fd;
auto ret = mInterface->dumpState(handle); const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
if (interface == nullptr) {
return DEAD_OBJECT;
}
auto ret = interface->dumpState(handle);
native_handle_delete(handle); native_handle_delete(handle);
if (!ret.isOk()) { if (!ret.isOk()) {
return INVALID_OPERATION; return INVALID_OPERATION;
@ -1408,8 +1601,14 @@ status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getPhysicalCameraChar
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::isSessionConfigurationSupported( status_t CameraProviderManager::ProviderInfo::DeviceInfo3::isSessionConfigurationSupported(
const hardware::camera::device::V3_4::StreamConfiguration &configuration, const hardware::camera::device::V3_4::StreamConfiguration &configuration,
bool *status /*out*/) const { bool *status /*out*/) {
auto castResult = device::V3_5::ICameraDevice::castFrom(mInterface);
const sp<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT> interface =
this->startDeviceInterface<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
if (interface == nullptr) {
return DEAD_OBJECT;
}
auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
sp<hardware::camera::device::V3_5::ICameraDevice> interface_3_5 = castResult; sp<hardware::camera::device::V3_5::ICameraDevice> interface_3_5 = castResult;
if (interface_3_5 == nullptr) { if (interface_3_5 == nullptr) {
return INVALID_OPERATION; return INVALID_OPERATION;

@ -18,6 +18,7 @@
#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_H #define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_H
#include <vector> #include <vector>
#include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <string> #include <string>
#include <mutex> #include <mutex>
@ -110,6 +111,14 @@ public:
virtual void onNewProviderRegistered() = 0; virtual void onNewProviderRegistered() = 0;
}; };
/**
* Represents the mode a camera device is currently in
*/
enum class DeviceMode {
TORCH,
CAMERA
};
/** /**
* Initialize the manager and give it a status listener; optionally accepts a service * Initialize the manager and give it a status listener; optionally accepts a service
* interaction proxy. * interaction proxy.
@ -182,7 +191,7 @@ public:
/** /**
* Check if a given camera device support setTorchMode API. * Check if a given camera device support setTorchMode API.
*/ */
bool supportSetTorchMode(const std::string &id); bool supportSetTorchMode(const std::string &id) const;
/** /**
* Turn on or off the flashlight on a given camera device. * Turn on or off the flashlight on a given camera device.
@ -212,6 +221,17 @@ public:
/*out*/ /*out*/
sp<hardware::camera::device::V1_0::ICameraDevice> *session); sp<hardware::camera::device::V1_0::ICameraDevice> *session);
/**
* Save the ICameraProvider while it is being used by a camera or torch client
*/
void saveRef(DeviceMode usageType, const std::string &cameraId,
sp<hardware::camera::provider::V2_4::ICameraProvider> provider);
/**
* Notify that the camera or torch is no longer being used by a camera client
*/
void removeRef(DeviceMode usageType, const std::string &cameraId);
/** /**
* IServiceNotification::onRegistration * IServiceNotification::onRegistration
* Invoked by the hardware service manager when a new camera provider is registered * Invoked by the hardware service manager when a new camera provider is registered
@ -259,21 +279,43 @@ private:
static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy; static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy;
// Mapping from CameraDevice IDs to CameraProviders. This map is used to keep the
// ICameraProvider alive while it is in use by the camera with the given ID for camera
// capabilities
std::unordered_map<std::string, sp<hardware::camera::provider::V2_4::ICameraProvider>>
mCameraProviderByCameraId;
// Mapping from CameraDevice IDs to CameraProviders. This map is used to keep the
// ICameraProvider alive while it is in use by the camera with the given ID for torch
// capabilities
std::unordered_map<std::string, sp<hardware::camera::provider::V2_4::ICameraProvider>>
mTorchProviderByCameraId;
// Lock for accessing mCameraProviderByCameraId and mTorchProviderByCameraId
std::mutex mProviderInterfaceMapLock;
struct ProviderInfo : struct ProviderInfo :
virtual public hardware::camera::provider::V2_4::ICameraProviderCallback, virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
virtual public hardware::hidl_death_recipient virtual public hardware::hidl_death_recipient
{ {
const std::string mProviderName; const std::string mProviderName;
const sp<hardware::camera::provider::V2_4::ICameraProvider> mInterface;
const metadata_vendor_id_t mProviderTagid; const metadata_vendor_id_t mProviderTagid;
sp<VendorTagDescriptor> mVendorTagDescriptor; sp<VendorTagDescriptor> mVendorTagDescriptor;
bool mSetTorchModeSupported;
bool mIsRemote;
// This pointer is used to keep a reference to the ICameraProvider that was last accessed.
wp<hardware::camera::provider::V2_4::ICameraProvider> mActiveInterface;
sp<hardware::camera::provider::V2_4::ICameraProvider> mSavedInterface;
ProviderInfo(const std::string &providerName, ProviderInfo(const std::string &providerName,
sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
CameraProviderManager *manager); CameraProviderManager *manager);
~ProviderInfo(); ~ProviderInfo();
status_t initialize(); status_t initialize(sp<hardware::camera::provider::V2_4::ICameraProvider>& interface);
const sp<hardware::camera::provider::V2_4::ICameraProvider> startProviderInterface();
const std::string& getType() const; const std::string& getType() const;
@ -308,16 +350,20 @@ private:
const metadata_vendor_id_t mProviderTagid; const metadata_vendor_id_t mProviderTagid;
bool mIsLogicalCamera; bool mIsLogicalCamera;
std::vector<std::string> mPhysicalIds; std::vector<std::string> mPhysicalIds;
hardware::CameraInfo mInfo;
sp<IBase> mSavedInterface;
const hardware::camera::common::V1_0::CameraResourceCost mResourceCost; const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;
hardware::camera::common::V1_0::CameraDeviceStatus mStatus; hardware::camera::common::V1_0::CameraDeviceStatus mStatus;
sp<ProviderInfo> mParentProvider;
bool hasFlashUnit() const { return mHasFlashUnit; } bool hasFlashUnit() const { return mHasFlashUnit; }
virtual status_t setTorchMode(bool enabled) = 0; virtual status_t setTorchMode(bool enabled) = 0;
virtual status_t getCameraInfo(hardware::CameraInfo *info) const = 0; virtual status_t getCameraInfo(hardware::CameraInfo *info) const = 0;
virtual bool isAPI1Compatible() const = 0; virtual bool isAPI1Compatible() const = 0;
virtual status_t dumpState(int fd) const = 0; virtual status_t dumpState(int fd) = 0;
virtual status_t getCameraCharacteristics(CameraMetadata *characteristics) const { virtual status_t getCameraCharacteristics(CameraMetadata *characteristics) const {
(void) characteristics; (void) characteristics;
return INVALID_OPERATION; return INVALID_OPERATION;
@ -331,19 +377,23 @@ private:
virtual status_t isSessionConfigurationSupported( virtual status_t isSessionConfigurationSupported(
const hardware::camera::device::V3_4::StreamConfiguration &/*configuration*/, const hardware::camera::device::V3_4::StreamConfiguration &/*configuration*/,
bool * /*status*/) bool * /*status*/) {
const {
return INVALID_OPERATION; return INVALID_OPERATION;
} }
template<class InterfaceT>
sp<InterfaceT> startDeviceInterface();
DeviceInfo(const std::string& name, const metadata_vendor_id_t tagId, DeviceInfo(const std::string& name, const metadata_vendor_id_t tagId,
const std::string &id, const hardware::hidl_version& version, const std::string &id, const hardware::hidl_version& version,
const std::vector<std::string>& publicCameraIds, const std::vector<std::string>& publicCameraIds,
const hardware::camera::common::V1_0::CameraResourceCost& resourceCost) : const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
sp<ProviderInfo> parentProvider) :
mName(name), mId(id), mVersion(version), mProviderTagid(tagId), mName(name), mId(id), mVersion(version), mProviderTagid(tagId),
mIsLogicalCamera(false), mResourceCost(resourceCost), mIsLogicalCamera(false), mResourceCost(resourceCost),
mStatus(hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT), mStatus(hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT),
mHasFlashUnit(false), mPublicCameraIds(publicCameraIds) {} mParentProvider(parentProvider), mHasFlashUnit(false),
mPublicCameraIds(publicCameraIds) {}
virtual ~DeviceInfo(); virtual ~DeviceInfo();
protected: protected:
bool mHasFlashUnit; bool mHasFlashUnit;
@ -351,6 +401,14 @@ private:
template<class InterfaceT> template<class InterfaceT>
static status_t setTorchMode(InterfaceT& interface, bool enabled); static status_t setTorchMode(InterfaceT& interface, bool enabled);
template<class InterfaceT>
status_t setTorchModeForDevice(bool enabled) {
// Don't save the ICameraProvider interface here because we assume that this was
// called from CameraProviderManager::setTorchMode(), which does save it.
const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
return DeviceInfo::setTorchMode(interface, enabled);
}
}; };
std::vector<std::unique_ptr<DeviceInfo>> mDevices; std::vector<std::unique_ptr<DeviceInfo>> mDevices;
std::unordered_set<std::string> mUniqueCameraIds; std::unordered_set<std::string> mUniqueCameraIds;
@ -366,32 +424,32 @@ private:
// HALv1-specific camera fields, including the actual device interface // HALv1-specific camera fields, including the actual device interface
struct DeviceInfo1 : public DeviceInfo { struct DeviceInfo1 : public DeviceInfo {
typedef hardware::camera::device::V1_0::ICameraDevice InterfaceT; typedef hardware::camera::device::V1_0::ICameraDevice InterfaceT;
const sp<InterfaceT> mInterface;
virtual status_t setTorchMode(bool enabled) override; virtual status_t setTorchMode(bool enabled) override;
virtual status_t getCameraInfo(hardware::CameraInfo *info) const override; virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
//In case of Device1Info assume that we are always API1 compatible //In case of Device1Info assume that we are always API1 compatible
virtual bool isAPI1Compatible() const override { return true; } virtual bool isAPI1Compatible() const override { return true; }
virtual status_t dumpState(int fd) const override; virtual status_t dumpState(int fd) override;
DeviceInfo1(const std::string& name, const metadata_vendor_id_t tagId, DeviceInfo1(const std::string& name, const metadata_vendor_id_t tagId,
const std::string &id, uint16_t minorVersion, const std::string &id, uint16_t minorVersion,
const hardware::camera::common::V1_0::CameraResourceCost& resourceCost, const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
sp<ProviderInfo> parentProvider,
const std::vector<std::string>& publicCameraIds, const std::vector<std::string>& publicCameraIds,
sp<InterfaceT> interface); sp<InterfaceT> interface);
virtual ~DeviceInfo1(); virtual ~DeviceInfo1();
private: private:
CameraParameters2 mDefaultParameters; CameraParameters2 mDefaultParameters;
status_t cacheCameraInfo(sp<InterfaceT> interface);
}; };
// HALv3-specific camera fields, including the actual device interface // HALv3-specific camera fields, including the actual device interface
struct DeviceInfo3 : public DeviceInfo { struct DeviceInfo3 : public DeviceInfo {
typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT; typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;
const sp<InterfaceT> mInterface;
virtual status_t setTorchMode(bool enabled) override; virtual status_t setTorchMode(bool enabled) override;
virtual status_t getCameraInfo(hardware::CameraInfo *info) const override; virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
virtual bool isAPI1Compatible() const override; virtual bool isAPI1Compatible() const override;
virtual status_t dumpState(int fd) const override; virtual status_t dumpState(int fd) override;
virtual status_t getCameraCharacteristics( virtual status_t getCameraCharacteristics(
CameraMetadata *characteristics) const override; CameraMetadata *characteristics) const override;
virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId, virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
@ -399,11 +457,12 @@ private:
virtual status_t isSessionConfigurationSupported( virtual status_t isSessionConfigurationSupported(
const hardware::camera::device::V3_4::StreamConfiguration &configuration, const hardware::camera::device::V3_4::StreamConfiguration &configuration,
bool *status /*out*/) bool *status /*out*/)
const override; override;
DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId, DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId,
const std::string &id, uint16_t minorVersion, const std::string &id, uint16_t minorVersion,
const hardware::camera::common::V1_0::CameraResourceCost& resourceCost, const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
sp<ProviderInfo> parentProvider,
const std::vector<std::string>& publicCameraIds, sp<InterfaceT> interface); const std::vector<std::string>& publicCameraIds, sp<InterfaceT> interface);
virtual ~DeviceInfo3(); virtual ~DeviceInfo3();
private: private:
@ -430,11 +489,11 @@ private:
template<class DeviceInfoT> template<class DeviceInfoT>
std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &name, std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &name,
const metadata_vendor_id_t tagId, const std::string &id, const metadata_vendor_id_t tagId, const std::string &id,
uint16_t minorVersion) const; uint16_t minorVersion);
// Helper for initializeDeviceInfo to use the right CameraProvider get method. // Helper for initializeDeviceInfo to use the right CameraProvider get method.
template<class InterfaceT> template<class InterfaceT>
sp<InterfaceT> getDeviceInterface(const std::string &name) const; sp<InterfaceT> startDeviceInterface(const std::string &name);
// Parse provider instance name for type and id // Parse provider instance name for type and id
static status_t parseProviderName(const std::string& name, static status_t parseProviderName(const std::string& name,
@ -468,6 +527,14 @@ private:
std::vector<sp<ProviderInfo>> mProviders; std::vector<sp<ProviderInfo>> mProviders;
void addProviderToMap(
const std::string &cameraId,
sp<hardware::camera::provider::V2_4::ICameraProvider> provider,
bool isTorchUsage);
void removeCameraIdFromMap(
std::unordered_map<std::string, sp<hardware::camera::provider::V2_4::ICameraProvider>> &map,
const std::string &cameraId);
static const char* deviceStatusToString( static const char* deviceStatusToString(
const hardware::camera::common::V1_0::CameraDeviceStatus&); const hardware::camera::common::V1_0::CameraDeviceStatus&);
static const char* torchStatusToString( static const char* torchStatusToString(

Loading…
Cancel
Save