Add AidlProviderInfo to handle aidl hal providers.
Bug: 196432585
Test: GCA; Record videos and take pictures (Basic validity)
Test: Camera CTS with AIDL provider
Test: Use Camera VNDK
Change-Id: I8c2bf49100c45d5f09f6ef97a0d5739ebc2199d7
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/services/camera/libcameraservice/common/CameraProviderInfoTemplated.h b/services/camera/libcameraservice/common/CameraProviderInfoTemplated.h
new file mode 100644
index 0000000..db7692a
--- /dev/null
+++ b/services/camera/libcameraservice/common/CameraProviderInfoTemplated.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SERVERS_CAMERA_CAMERAPROVIDERINFO_TEMPLATEDH
+#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDERINFO_TEMPLATEDH
+
+#include "common/CameraProviderManager.h"
+
+namespace android {
+
+template <class VendorTagSectionVectorType, class VendorTagSectionType>
+status_t IdlVendorTagDescriptor::createDescriptorFromIdl(
+ const VendorTagSectionVectorType& vts,
+ sp<VendorTagDescriptor>& descriptor) {
+
+ int tagCount = 0;
+
+ for (size_t s = 0; s < vts.size(); s++) {
+ tagCount += vts[s].tags.size();
+ }
+
+ if (tagCount < 0 || tagCount > INT32_MAX) {
+ ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
+ return BAD_VALUE;
+ }
+
+ Vector<uint32_t> tagArray;
+ LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
+ "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
+ sp<IdlVendorTagDescriptor> desc = new IdlVendorTagDescriptor();
+ desc->mTagCount = tagCount;
+
+ SortedVector<String8> sections;
+ KeyedVector<uint32_t, String8> tagToSectionMap;
+
+ int idx = 0;
+ for (size_t s = 0; s < vts.size(); s++) {
+ const VendorTagSectionType& section = vts[s];
+ const char *sectionName = section.sectionName.c_str();
+ if (sectionName == NULL) {
+ ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
+ return BAD_VALUE;
+ }
+ String8 sectionString(sectionName);
+ sections.add(sectionString);
+
+ for (size_t j = 0; j < section.tags.size(); j++) {
+ uint32_t tag = section.tags[j].tagId;
+ if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
+ ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+
+ tagArray.editItemAt(idx++) = section.tags[j].tagId;
+
+ const char *tagName = section.tags[j].tagName.c_str();
+ if (tagName == NULL) {
+ ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+ desc->mTagToNameMap.add(tag, String8(tagName));
+ tagToSectionMap.add(tag, sectionString);
+
+ int tagType = (int) section.tags[j].tagType;
+ if (tagType < 0 || tagType >= NUM_TYPES) {
+ ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
+ return BAD_VALUE;
+ }
+ desc->mTagToTypeMap.add(tag, tagType);
+ }
+ }
+
+ desc->mSections = sections;
+
+ for (size_t i = 0; i < tagArray.size(); ++i) {
+ uint32_t tag = tagArray[i];
+ String8 sectionString = tagToSectionMap.valueFor(tag);
+
+ // Set up tag to section index map
+ ssize_t index = sections.indexOf(sectionString);
+ LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
+ desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
+
+ // Set up reverse mapping
+ ssize_t reverseIndex = -1;
+ if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
+ KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+ reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
+ }
+ desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
+ }
+
+ descriptor = std::move(desc);
+ return OK;
+}
+
+
+} // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 4227d28..5cab157 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -20,15 +20,18 @@
#include "CameraProviderManager.h"
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
#include <android/hardware/camera/device/3.8/ICameraDevice.h>
#include <algorithm>
#include <chrono>
#include "common/DepthPhotoProcessor.h"
#include "hidl/HidlProviderInfo.h"
+#include "aidl/AidlProviderInfo.h"
#include <dlfcn.h>
#include <future>
#include <inttypes.h>
+#include <android/binder_manager.h>
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl/ServiceManagement.h>
#include <functional>
@@ -59,12 +62,43 @@
const float CameraProviderManager::kDepthARTolerance = .1f;
+// AIDL Devices start with major version 1, offset added to bring them up to HIDL.
+const uint16_t kAidlDeviceMajorOffset = 2;
+// AIDL Devices start with minor version 1, offset added to bring them up to HIDL.
+const uint16_t kAidlDeviceMinorOffset = 7;
+
CameraProviderManager::HidlServiceInteractionProxyImpl
CameraProviderManager::sHidlServiceInteractionProxy{};
CameraProviderManager::~CameraProviderManager() {
}
+const char* FrameworkTorchStatusToString(const TorchModeStatus& s) {
+ switch (s) {
+ case TorchModeStatus::NOT_AVAILABLE:
+ return "NOT_AVAILABLE";
+ case TorchModeStatus::AVAILABLE_OFF:
+ return "AVAILABLE_OFF";
+ case TorchModeStatus::AVAILABLE_ON:
+ return "AVAILABLE_ON";
+ }
+ ALOGW("Unexpected HAL torch mode status code %d", s);
+ return "UNKNOWN_STATUS";
+}
+
+const char* FrameworkDeviceStatusToString(const CameraDeviceStatus& s) {
+ switch (s) {
+ case CameraDeviceStatus::NOT_PRESENT:
+ return "NOT_PRESENT";
+ case CameraDeviceStatus::PRESENT:
+ return "PRESENT";
+ case CameraDeviceStatus::ENUMERATING:
+ return "ENUMERATING";
+ }
+ ALOGW("Unexpected HAL device status code %d", s);
+ return "UNKNOWN_STATUS";
+}
+
hardware::hidl_vec<hardware::hidl_string>
CameraProviderManager::HidlServiceInteractionProxyImpl::listServices() {
hardware::hidl_vec<hardware::hidl_string> ret;
@@ -78,17 +112,9 @@
return ret;
}
-status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
- HidlServiceInteractionProxy* hidlProxy) {
- std::lock_guard<std::mutex> lock(mInterfaceMutex);
- if (hidlProxy == nullptr) {
- ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
- return BAD_VALUE;
- }
- mListener = listener;
+status_t CameraProviderManager::tryToInitAndAddHidlProvidersLocked(
+ HidlServiceInteractionProxy *hidlProxy) {
mHidlServiceProxy = hidlProxy;
- mDeviceState = 0;
-
// Registering will trigger notifications for all already-known providers
bool success = mHidlServiceProxy->registerForNotifications(
/* instance name, empty means no filter */ "",
@@ -102,10 +128,54 @@
for (const auto& instance : mHidlServiceProxy->listServices()) {
this->addHidlProviderLocked(instance);
}
+ return OK;
+}
+
+static std::string getFullAidlProviderName(const std::string instance) {
+ std::string aidlHalServiceDescriptor =
+ std::string(aidl::android::hardware::camera::provider::ICameraProvider::descriptor);
+ return aidlHalServiceDescriptor + "/" + instance;
+}
+
+status_t CameraProviderManager::tryToAddAidlProvidersLocked() {
+ const char * aidlHalServiceDescriptor =
+ aidl::android::hardware::camera::provider::ICameraProvider::descriptor;
+ auto sm = defaultServiceManager();
+ auto aidlProviders = sm->getDeclaredInstances(
+ String16(aidlHalServiceDescriptor));
+ for (const auto &aidlInstance : aidlProviders) {
+ std::string aidlServiceName =
+ getFullAidlProviderName(std::string(String8(aidlInstance).c_str()));
+ auto res = sm->registerForNotifications(String16(aidlServiceName.c_str()), this);
+ if (res != OK) {
+ ALOGE("%s Unable to register for notifications with AIDL service manager",
+ __FUNCTION__);
+ return res;
+ }
+ addAidlProviderLocked(aidlServiceName.c_str());
+ }
+ return OK;
+}
+
+status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
+ HidlServiceInteractionProxy* hidlProxy) {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+ if (hidlProxy == nullptr) {
+ ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ mListener = listener;
+ mDeviceState = 0;
+ auto res = tryToInitAndAddHidlProvidersLocked(hidlProxy);
+ if (res != OK) {
+ // Logging done in called function;
+ return res;
+ }
+ res = tryToAddAidlProvidersLocked();
IPCThreadState::self()->flushCommands();
- return OK;
+ return res;
}
std::pair<int, int> CameraProviderManager::getCameraCount() const {
@@ -380,6 +450,22 @@
return false;
}
+template <class ProviderInfoType, class HalCameraProviderType>
+status_t CameraProviderManager::setTorchModeT(sp<ProviderInfo> &parentProvider,
+ std::shared_ptr<HalCameraProvider> *halCameraProvider) {
+ if (halCameraProvider == nullptr) {
+ return BAD_VALUE;
+ }
+ ProviderInfoType *idlProviderInfo = static_cast<ProviderInfoType *>(parentProvider.get());
+ auto idlInterface = idlProviderInfo->startProviderInterface();
+ if (idlInterface == nullptr) {
+ return DEAD_OBJECT;
+ }
+ *halCameraProvider =
+ std::make_shared<HalCameraProviderType>(idlInterface, idlInterface->descriptor);
+ return OK;
+}
+
status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
@@ -394,18 +480,19 @@
}
std::shared_ptr<HalCameraProvider> halCameraProvider = nullptr;
IPCTransport providerTransport = parentProvider->getIPCTransport();
+ status_t res = OK;
if (providerTransport == IPCTransport::HIDL) {
- HidlProviderInfo * hidlProviderInfo = static_cast<HidlProviderInfo *>(parentProvider.get());
- const sp<provider::V2_4::ICameraProvider> hidlInterface =
- hidlProviderInfo->startProviderInterface();
- if (hidlInterface == nullptr) {
- return DEAD_OBJECT;
+ res = setTorchModeT<HidlProviderInfo, HidlHalCameraProvider>(parentProvider,
+ &halCameraProvider);
+ if (res != OK) {
+ return res;
}
- halCameraProvider =
- std::make_shared<HidlHalCameraProvider>(hidlInterface, hidlInterface->descriptor);
} else if (providerTransport == IPCTransport::AIDL) {
- ALOGE("%s AIDL hal providers not supported yet", __FUNCTION__);
- return INVALID_OPERATION;
+ res = setTorchModeT<AidlProviderInfo, AidlHalCameraProvider>(parentProvider,
+ &halCameraProvider);
+ if (res != OK) {
+ return res;
+ }
} else {
ALOGE("%s Invalid provider transport", __FUNCTION__);
return INVALID_OPERATION;
@@ -518,6 +605,48 @@
return res;
}
+status_t CameraProviderManager::openAidlSession(const std::string &id,
+ const std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
+ /*out*/
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> *session) {
+
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+ auto deviceInfo = findDeviceInfoLocked(id,
+ /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
+ if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+
+ auto *aidlDeviceInfo3 = static_cast<AidlProviderInfo::AidlDeviceInfo3*>(deviceInfo);
+ sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
+ if (parentProvider == nullptr) {
+ return DEAD_OBJECT;
+ }
+ auto provider =
+ static_cast<AidlProviderInfo *>(parentProvider.get())->startProviderInterface();
+ if (provider == nullptr) {
+ return DEAD_OBJECT;
+ }
+ std::shared_ptr<HalCameraProvider> halCameraProvider =
+ std::make_shared<AidlHalCameraProvider>(provider, provider->descriptor);
+ saveRef(DeviceMode::CAMERA, id, halCameraProvider);
+
+ auto interface = aidlDeviceInfo3->startDeviceInterface();
+ if (interface == nullptr) {
+ removeRef(DeviceMode::CAMERA, id);
+ return DEAD_OBJECT;
+ }
+
+ auto ret = interface->open(callback, session);
+ if (!ret.isOk()) {
+ removeRef(DeviceMode::CAMERA, id);
+ ALOGE("%s: Transaction error opening a session for camera device %s: %s",
+ __FUNCTION__, id.c_str(), ret.getMessage());
+ return DEAD_OBJECT;
+ }
+ return OK;
+}
+
status_t CameraProviderManager::openHidlSession(const std::string &id,
const sp<device::V3_2::ICameraDeviceCallback>& callback,
/*out*/
@@ -622,6 +751,26 @@
}
}
+// We ignore sp<IBinder> param here since we need std::shared_ptr<...> which
+// will be retrieved through the ndk api through addAidlProviderLocked ->
+// tryToInitializeAidlProvider.
+void CameraProviderManager::onServiceRegistration(const String16 &name, const sp<IBinder>&) {
+ status_t res = OK;
+ std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
+ {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+ res = addAidlProviderLocked(String8(name).c_str());
+ }
+
+ sp<StatusListener> listener = getStatusListener();
+ if (nullptr != listener.get() && res == OK) {
+ listener->onNewProviderRegistered();
+ }
+
+ IPCThreadState::self()->flushCommands();
+}
+
hardware::Return<void> CameraProviderManager::onRegistration(
const hardware::hidl_string& /*fqName*/,
const hardware::hidl_string& name,
@@ -653,6 +802,59 @@
return OK;
}
+void CameraProviderManager::ProviderInfo::initializeProviderInfoCommon(
+ const std::vector<std::string> &devices) {
+
+ sp<StatusListener> listener = mManager->getStatusListener();
+
+ for (auto& device : devices) {
+ std::string id;
+ status_t res = addDevice(device, CameraDeviceStatus::PRESENT, &id);
+ if (res != OK) {
+ ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
+ __FUNCTION__, device.c_str(), strerror(-res), res);
+ continue;
+ }
+ }
+
+ ALOGI("Camera provider %s ready with %zu camera devices",
+ mProviderName.c_str(), mDevices.size());
+
+ // Process cached status callbacks
+ std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus =
+ std::make_unique<std::vector<CameraStatusInfoT>>();
+ {
+ std::lock_guard<std::mutex> lock(mInitLock);
+
+ for (auto& statusInfo : mCachedStatus) {
+ std::string id, physicalId;
+ status_t res = OK;
+ if (statusInfo.isPhysicalCameraStatus) {
+ res = physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
+ statusInfo.cameraId, statusInfo.physicalCameraId, statusInfo.status);
+ } else {
+ res = cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId, statusInfo.status);
+ }
+ if (res == OK) {
+ cachedStatus->emplace_back(statusInfo.isPhysicalCameraStatus,
+ id.c_str(), physicalId.c_str(), statusInfo.status);
+ }
+ }
+ mCachedStatus.clear();
+
+ mInitialized = true;
+ }
+
+ // The cached status change callbacks cannot be fired directly from this
+ // function, due to same-thread deadlock trying to acquire mInterfaceMutex
+ // twice.
+ if (listener != nullptr) {
+ mInitialStatusCallbackFuture = std::async(std::launch::async,
+ &CameraProviderManager::ProviderInfo::notifyInitialStatusChange, this,
+ listener, std::move(cachedStatus));
+ }
+}
+
CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
const std::string& id,
hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
@@ -1387,6 +1589,23 @@
return falseRet;
}
+status_t CameraProviderManager::tryToInitializeAidlProviderLocked(
+ const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
+ using aidl::android::hardware::camera::provider::ICameraProvider;
+ std::shared_ptr<ICameraProvider> interface =
+ ICameraProvider::fromBinder(ndk::SpAIBinder(
+ AServiceManager_getService(providerName.c_str())));
+
+ if (interface == nullptr) {
+ ALOGW("%s: AIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
+ providerName.c_str());
+ return BAD_VALUE;
+ }
+
+ AidlProviderInfo *aidlProviderInfo = static_cast<AidlProviderInfo *>(providerInfo.get());
+ return aidlProviderInfo->initializeAidlProvider(interface, mDeviceState);
+}
+
status_t CameraProviderManager::tryToInitializeHidlProviderLocked(
const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
sp<provider::V2_4::ICameraProvider> interface;
@@ -1395,7 +1614,7 @@
if (interface == nullptr) {
// The interface may not be started yet. In that case, this is not a
// fatal error.
- ALOGW("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
+ ALOGW("%s: HIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
providerName.c_str());
return BAD_VALUE;
}
@@ -1404,6 +1623,54 @@
return hidlProviderInfo->initializeHidlProvider(interface, mDeviceState);
}
+status_t CameraProviderManager::addAidlProviderLocked(const std::string& newProvider) {
+ // Several camera provider instances can be temporarily present.
+ // Defer initialization of a new instance until the older instance is properly removed.
+ auto providerInstance = newProvider + "-" + std::to_string(mProviderInstanceId);
+ bool providerPresent = false;
+ bool preexisting =
+ (mAidlProviderWithBinders.find(newProvider) != mAidlProviderWithBinders.end());
+
+ // We need to use the extracted provider name here since 'newProvider' has
+ // the fully qualified name of the provider service in case of AIDL. We want
+ // just instance name.
+ using aidl::android::hardware::camera::provider::ICameraProvider;
+ std::string extractedProviderName =
+ newProvider.substr(std::string(ICameraProvider::descriptor).size() + 1);
+ for (const auto& providerInfo : mProviders) {
+ if (providerInfo->mProviderName == extractedProviderName) {
+ ALOGW("%s: Camera provider HAL with name '%s' already registered",
+ __FUNCTION__, newProvider.c_str());
+ // Do not add new instances for lazy HAL external provider or aidl
+ // binders previously seen.
+ if (preexisting || providerInfo->isExternalLazyHAL()) {
+ return ALREADY_EXISTS;
+ } else {
+ ALOGW("%s: The new provider instance will get initialized immediately after the"
+ " currently present instance is removed!", __FUNCTION__);
+ providerPresent = true;
+ break;
+ }
+ }
+ }
+
+ sp<AidlProviderInfo> providerInfo =
+ new AidlProviderInfo(extractedProviderName, providerInstance, this);
+
+ if (!providerPresent) {
+ status_t res = tryToInitializeAidlProviderLocked(newProvider, providerInfo);
+ if (res != OK) {
+ return res;
+ }
+ mAidlProviderWithBinders.emplace(newProvider);
+ }
+
+ mProviders.push_back(providerInfo);
+ mProviderInstanceId++;
+
+ return OK;
+}
+
status_t CameraProviderManager::addHidlProviderLocked(const std::string& newProvider,
bool preexisting) {
// Several camera provider instances can be temporarily present.
@@ -1467,9 +1734,13 @@
for (const auto& providerInfo : mProviders) {
if (providerInfo->mProviderName == removedProviderName) {
IPCTransport providerTransport = providerInfo->getIPCTransport();
+ std::string removedAidlProviderName = getFullAidlProviderName(removedProviderName);
switch(providerTransport) {
case IPCTransport::HIDL:
return tryToInitializeHidlProviderLocked(removedProviderName, providerInfo);
+ case IPCTransport::AIDL:
+ return tryToInitializeAidlProviderLocked(removedAidlProviderName,
+ providerInfo);
default:
ALOGE("%s Unsupported Transport %d", __FUNCTION__, providerTransport);
}
@@ -1513,6 +1784,70 @@
return mType;
}
+status_t CameraProviderManager::ProviderInfo::addDevice(
+ const std::string& name, CameraDeviceStatus initialStatus,
+ /*out*/ std::string* parsedId) {
+
+ ALOGI("Enumerating new camera device: %s", name.c_str());
+
+ uint16_t major, minor;
+ std::string type, id;
+
+ status_t res = parseDeviceName(name, &major, &minor, &type, &id);
+ if (res != OK) {
+ return res;
+ }
+ if (getIPCTransport() == IPCTransport::AIDL) {
+ // Till HIDL support exists, map AIDL versions to HIDL.
+ // TODO:b/196432585 Explore if we can get rid of this.
+ major += kAidlDeviceMajorOffset;
+ minor += kAidlDeviceMinorOffset;
+ }
+
+ if (type != mType) {
+ ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
+ type.c_str(), mType.c_str());
+ return BAD_VALUE;
+ }
+ if (mManager->isValidDeviceLocked(id, major)) {
+ ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
+ name.c_str(), id.c_str(), major);
+ return BAD_VALUE;
+ }
+
+ std::unique_ptr<DeviceInfo> deviceInfo;
+ switch (major) {
+ case 3:
+ deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
+ break;
+ default:
+ ALOGE("%s: Device %s: Unsupported IDL device HAL major version %d:", __FUNCTION__,
+ name.c_str(), major);
+ return BAD_VALUE;
+ }
+ if (deviceInfo == nullptr) return BAD_VALUE;
+ deviceInfo->notifyDeviceStateChange(getDeviceState());
+ deviceInfo->mStatus = initialStatus;
+ bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
+
+ mDevices.push_back(std::move(deviceInfo));
+
+ mUniqueCameraIds.insert(id);
+ if (isAPI1Compatible) {
+ // addDevice can be called more than once for the same camera id if HAL
+ // supports openLegacy.
+ if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
+ id) == mUniqueAPI1CompatibleCameraIds.end()) {
+ mUniqueAPI1CompatibleCameraIds.push_back(id);
+ }
+ }
+
+ if (parsedId != nullptr) {
+ *parsedId = id;
+ }
+ return OK;
+}
+
void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
if ((*it)->mId == id) {
@@ -1643,6 +1978,197 @@
return mConcurrentCameraIdCombinations;
}
+void CameraProviderManager::ProviderInfo::cameraDeviceStatusChangeInternal(
+ const std::string& cameraDeviceName, CameraDeviceStatus newStatus) {
+ sp<StatusListener> listener;
+ std::string id;
+ std::lock_guard<std::mutex> lock(mInitLock);
+ CameraDeviceStatus internalNewStatus = newStatus;
+ if (!mInitialized) {
+ mCachedStatus.emplace_back(false /*isPhysicalCameraStatus*/,
+ cameraDeviceName.c_str(), std::string().c_str(),
+ internalNewStatus);
+ return;
+ }
+
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (OK != cameraDeviceStatusChangeLocked(&id, cameraDeviceName, newStatus)) {
+ return;
+ }
+ listener = mManager->getStatusListener();
+ }
+
+ // Call without lock held to allow reentrancy into provider manager
+ if (listener != nullptr) {
+ listener->onDeviceStatusChanged(String8(id.c_str()), internalNewStatus);
+ }
+}
+
+status_t CameraProviderManager::ProviderInfo::cameraDeviceStatusChangeLocked(
+ std::string* id, const std::string& cameraDeviceName,
+ CameraDeviceStatus newStatus) {
+ bool known = false;
+ std::string cameraId;
+ for (auto& deviceInfo : mDevices) {
+ if (deviceInfo->mName == cameraDeviceName) {
+ Mutex::Autolock l(deviceInfo->mDeviceAvailableLock);
+ ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
+ FrameworkDeviceStatusToString(newStatus),
+ FrameworkDeviceStatusToString(deviceInfo->mStatus));
+ deviceInfo->mStatus = newStatus;
+ // TODO: Handle device removal (NOT_PRESENT)
+ cameraId = deviceInfo->mId;
+ known = true;
+ deviceInfo->mIsDeviceAvailable =
+ (newStatus == CameraDeviceStatus::PRESENT);
+ deviceInfo->mDeviceAvailableSignal.signal();
+ break;
+ }
+ }
+ // Previously unseen device; status must not be NOT_PRESENT
+ if (!known) {
+ if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
+ ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
+ mProviderName.c_str(), cameraDeviceName.c_str());
+ return BAD_VALUE;
+ }
+ addDevice(cameraDeviceName, newStatus, &cameraId);
+ } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
+ removeDevice(cameraId);
+ } else if (isExternalLazyHAL()) {
+ // Do not notify CameraService for PRESENT->PRESENT (lazy HAL restart)
+ // because NOT_AVAILABLE is set on CameraService::connect and a PRESENT
+ // notif. would overwrite it
+ return BAD_VALUE;
+ }
+
+ if (reCacheConcurrentStreamingCameraIdsLocked() != OK) {
+ ALOGE("%s: CameraProvider %s could not re-cache concurrent streaming camera id list ",
+ __FUNCTION__, mProviderName.c_str());
+ }
+ *id = cameraId;
+ return OK;
+}
+
+void CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChangeInternal(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ CameraDeviceStatus newStatus) {
+ sp<StatusListener> listener;
+ std::string id;
+ std::string physicalId;
+ std::lock_guard<std::mutex> lock(mInitLock);
+ if (!mInitialized) {
+ mCachedStatus.emplace_back(true /*isPhysicalCameraStatus*/, cameraDeviceName,
+ physicalCameraDeviceName, newStatus);
+ return;
+ }
+
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+
+ if (OK != physicalCameraDeviceStatusChangeLocked(&id, &physicalId, cameraDeviceName,
+ physicalCameraDeviceName, newStatus)) {
+ return;
+ }
+
+ listener = mManager->getStatusListener();
+ }
+ // Call without lock held to allow reentrancy into provider manager
+ if (listener != nullptr) {
+ listener->onDeviceStatusChanged(String8(id.c_str()),
+ String8(physicalId.c_str()), newStatus);
+ }
+ return;
+}
+
+status_t CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChangeLocked(
+ std::string* id, std::string* physicalId,
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ CameraDeviceStatus newStatus) {
+ bool known = false;
+ std::string cameraId;
+ for (auto& deviceInfo : mDevices) {
+ if (deviceInfo->mName == cameraDeviceName) {
+ cameraId = deviceInfo->mId;
+ if (!deviceInfo->mIsLogicalCamera) {
+ ALOGE("%s: Invalid combination of camera id %s, physical id %s",
+ __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
+ return BAD_VALUE;
+ }
+ if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
+ physicalCameraDeviceName) == deviceInfo->mPhysicalIds.end()) {
+ ALOGE("%s: Invalid combination of camera id %s, physical id %s",
+ __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
+ return BAD_VALUE;
+ }
+ ALOGI("Camera device %s physical device %s status is now %s",
+ cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(),
+ FrameworkDeviceStatusToString(newStatus));
+ known = true;
+ break;
+ }
+ }
+ // Previously unseen device; status must not be NOT_PRESENT
+ if (!known) {
+ ALOGW("Camera provider %s says an unknown camera device %s-%s is not present. Curious.",
+ mProviderName.c_str(), cameraDeviceName.c_str(),
+ physicalCameraDeviceName.c_str());
+ return BAD_VALUE;
+ }
+
+ *id = cameraId;
+ *physicalId = physicalCameraDeviceName.c_str();
+ return OK;
+}
+
+void CameraProviderManager::ProviderInfo::torchModeStatusChangeInternal(
+ const std::string& cameraDeviceName,
+ TorchModeStatus newStatus) {
+ sp<StatusListener> listener;
+ SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
+ std::string id;
+ bool known = false;
+ {
+ // Hold mLock for accessing mDevices
+ std::lock_guard<std::mutex> lock(mLock);
+ for (auto& deviceInfo : mDevices) {
+ if (deviceInfo->mName == cameraDeviceName) {
+ ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
+ FrameworkTorchStatusToString(newStatus));
+ id = deviceInfo->mId;
+ known = true;
+ systemCameraKind = deviceInfo->mSystemCameraKind;
+ if (TorchModeStatus::AVAILABLE_ON != newStatus) {
+ mManager->removeRef(CameraProviderManager::DeviceMode::TORCH, id);
+ }
+ break;
+ }
+ }
+ if (!known) {
+ ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
+ mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
+ return;
+ }
+ // no lock needed since listener is set up only once during
+ // CameraProviderManager initialization and then never changed till it is
+ // destructed.
+ listener = mManager->getStatusListener();
+ }
+ // Call without lock held to allow reentrancy into provider manager
+ // The problem with holding mLock here is that we
+ // might be limiting re-entrancy : CameraService::onTorchStatusChanged calls
+ // back into CameraProviderManager which might try to hold mLock again (eg:
+ // findDeviceInfo, which should be holding mLock while iterating through
+ // each provider's devices).
+ if (listener != nullptr) {
+ listener->onTorchStatusChanged(String8(id.c_str()), newStatus, systemCameraKind);
+ }
+ return;
+}
+
void CameraProviderManager::ProviderInfo::notifyDeviceInfoStateChangeLocked(
int64_t newDeviceState) {
std::lock_guard<std::mutex> lock(mLock);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 4568209..b67a7fa 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -33,6 +33,7 @@
#include <utils/Errors.h>
#include <android/hardware/ICameraService.h>
#include <utils/IPCTransport.h>
+#include <aidl/android/hardware/camera/provider/ICameraProvider.h>
#include <android/hardware/camera/common/1.0/types.h>
#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
#include <android/hardware/camera/provider/2.6/ICameraProviderCallback.h>
@@ -97,6 +98,26 @@
#define CAMERA_DEVICE_API_VERSION_3_8 HARDWARE_DEVICE_API_VERSION(3, 8)
/**
+ * The vendor tag descriptor class that takes HIDL/AIDL vendor tag information as
+ * input. Not part of VendorTagDescriptor class because that class is used
+ * in AIDL generated sources which don't have access to AIDL / HIDL headers.
+ */
+class IdlVendorTagDescriptor : public VendorTagDescriptor {
+public:
+ /**
+ * Create a VendorTagDescriptor object from the HIDL/AIDL VendorTagSection
+ * vector.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ template <class VendorTagSectionVectorType, class VendorTagSectionType>
+ static status_t createDescriptorFromIdl(
+ const VendorTagSectionVectorType& vts,
+ /*out*/
+ sp<VendorTagDescriptor>& descriptor);
+};
+
+/**
* A manager for all camera providers available on an Android device.
*
* Responsible for enumerating providers and the individual camera devices
@@ -106,11 +127,13 @@
* opening them for active use.
*
*/
-class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification {
+class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification,
+ public virtual IServiceManager::LocalRegistrationCallback {
public:
// needs to be made friend strict since HidlProviderInfo needs to inherit
// from CameraProviderManager::ProviderInfo which isn't a public member.
friend struct HidlProviderInfo;
+ friend struct AidlProviderInfo;
~CameraProviderManager();
// Tiny proxy for the static methods in a HIDL interface that communicate with the hardware
@@ -315,6 +338,13 @@
*/
status_t notifyDeviceStateChange(int64_t newState);
+ status_t openAidlSession(const std::string &id,
+ const std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
+ /*out*/
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> *session);
+
+
/**
* Open an active session to a camera device.
*
@@ -339,6 +369,9 @@
const hardware::hidl_string& name,
bool preexisting) override;
+ // LocalRegistrationCallback::onServiceRegistration
+ virtual void onServiceRegistration(const String16& name, const sp<IBinder> &binder) override;
+
/**
* Dump out information about available providers and devices
*/
@@ -402,6 +435,17 @@
sp<hardware::camera::provider::V2_4::ICameraProvider> mCameraProvider;
};
+ struct AidlHalCameraProvider : public HalCameraProvider {
+ AidlHalCameraProvider(
+ const std::shared_ptr<
+ aidl::android::hardware::camera::provider::ICameraProvider> &provider,
+ const char *descriptor) :
+ HalCameraProvider(descriptor), mCameraProvider(provider) { };
+ private:
+ std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider> mCameraProvider;
+ };
+
+
// 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
@@ -418,10 +462,11 @@
std::mutex mProviderInterfaceMapLock;
struct ProviderInfo : public virtual RefBase {
friend struct HidlProviderInfo;
+ friend struct AidlProviderInfo;
const std::string mProviderName;
const std::string mProviderInstance;
const metadata_vendor_id_t mProviderTagid;
- int mMinorVersion;
+ int32_t mMinorVersion;
sp<VendorTagDescriptor> mVendorTagDescriptor;
bool mSetTorchModeSupported;
bool mIsRemote;
@@ -436,6 +481,7 @@
status_t dump(int fd, const Vector<String16>& args) const;
+ void initializeProviderInfoCommon(const std::vector<std::string> &devices);
/**
* Setup vendor tags for this provider
*/
@@ -452,6 +498,8 @@
virtual bool successfullyStartedProviderInterface() = 0;
+ virtual int64_t getDeviceState() = 0;
+
std::vector<std::unordered_set<std::string>> getConcurrentCameraIdCombinations();
/**
@@ -469,7 +517,6 @@
const std::set<std::string>& perfClassPrimaryCameraIds,
int targetSdkVersion, bool *isSupported) = 0;
-
/**
* Remove all devices associated with this provider and notify listeners
* with NOT_PRESENT state.
@@ -666,6 +713,14 @@
// End of scope for mInitLock
std::future<void> mInitialStatusCallbackFuture;
+
+ std::unique_ptr<ProviderInfo::DeviceInfo>
+ virtual initializeDeviceInfo(
+ const std::string &name, const metadata_vendor_id_t tagId,
+ const std::string &id, uint16_t minorVersion) = 0;
+
+ virtual status_t reCacheConcurrentStreamingCameraIdsLocked() = 0;
+
void notifyInitialStatusChange(sp<StatusListener> listener,
std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus);
@@ -682,10 +737,46 @@
// Generate vendor tag id
static metadata_vendor_id_t generateVendorTagId(const std::string &name);
+ status_t addDevice(
+ const std::string& name, CameraDeviceStatus initialStatus,
+ /*out*/ std::string* parsedId);
+
+ void cameraDeviceStatusChangeInternal(const std::string& cameraDeviceName,
+ CameraDeviceStatus newStatus);
+
+ status_t cameraDeviceStatusChangeLocked(
+ std::string* id, const std::string& cameraDeviceName,
+ CameraDeviceStatus newStatus);
+
+ void physicalCameraDeviceStatusChangeInternal(const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ CameraDeviceStatus newStatus);
+
+ status_t physicalCameraDeviceStatusChangeLocked(
+ std::string* id, std::string* physicalId,
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ CameraDeviceStatus newStatus);
+
+ void torchModeStatusChangeInternal(const std::string& cameraDeviceName,
+ TorchModeStatus newStatus);
+
void removeDevice(std::string id);
};
+ template <class ProviderInfoType, class HalCameraProviderType>
+ status_t setTorchModeT(sp<ProviderInfo> &parentProvider,
+ std::shared_ptr<HalCameraProvider> *halCameraProvider);
+
+ // Try to get hidl provider services declared. Expects mInterfaceMutex to be
+ // locked. Also registers for hidl provider service notifications.
+ status_t tryToInitAndAddHidlProvidersLocked(HidlServiceInteractionProxy *hidlProxy);
+
+ // Try to get aidl provider services declared. Expects mInterfaceMutex to be
+ // locked. Also registers for aidl provider service notifications.
+ status_t tryToAddAidlProvidersLocked();
+
/**
* Save the ICameraProvider while it is being used by a camera or torch client
*/
@@ -709,9 +800,14 @@
status_t addHidlProviderLocked(const std::string& newProvider, bool preexisting = false);
+ status_t addAidlProviderLocked(const std::string& newProvider);
+
status_t tryToInitializeHidlProviderLocked(const std::string& providerName,
const sp<ProviderInfo>& providerInfo);
+ status_t tryToInitializeAidlProviderLocked(const std::string& providerName,
+ const sp<ProviderInfo>& providerInfo);
+
bool isLogicalCameraLocked(const std::string& id, std::vector<std::string>* physicalCameraIds);
// No method corresponding to the same provider / member belonging to the
@@ -725,6 +821,8 @@
size_t mProviderInstanceId = 0;
std::vector<sp<ProviderInfo>> mProviders;
+ // Provider names of AIDL providers with retrieved binders.
+ std::set<std::string> mAidlProviderWithBinders;
static const char* deviceStatusToString(
const hardware::camera::common::V1_0::CameraDeviceStatus&);
@@ -744,6 +842,8 @@
std::vector<std::string>& systemCameraDeviceIds) const;
status_t usbDeviceDetached(const std::string &usbDeviceId);
+ ndk::ScopedAStatus onAidlRegistration(const std::string& in_name,
+ const ::ndk::SpAIBinder& in_binder);
};
} // namespace android
diff --git a/services/camera/libcameraservice/common/HalConversionsTemplated.h b/services/camera/libcameraservice/common/HalConversionsTemplated.h
new file mode 100644
index 0000000..96a715c
--- /dev/null
+++ b/services/camera/libcameraservice/common/HalConversionsTemplated.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SERVERS_CAMERA_HAL_CONVERSION_TEMPLATED_H
+#define ANDROID_SERVERS_CAMERA_HAL_CONVERSION_TEMPLATED_H
+
+#include "common/CameraProviderManager.h"
+
+#include <device3/Camera3StreamInterface.h>
+
+namespace android {
+
+template <class HalCameraDeviceStatus>
+HalCameraDeviceStatus mapFrameworkToHalCameraDeviceStatus(
+ const CameraDeviceStatus& s) {
+ switch(s) {
+ case CameraDeviceStatus::PRESENT:
+ return HalCameraDeviceStatus::PRESENT;
+ case CameraDeviceStatus::NOT_PRESENT:
+ return HalCameraDeviceStatus::NOT_PRESENT;
+ case CameraDeviceStatus::ENUMERATING:
+ return HalCameraDeviceStatus::ENUMERATING;
+ }
+ ALOGW("Unexpectedcamera device status code %d", s);
+ return HalCameraDeviceStatus::NOT_PRESENT;
+}
+
+template <class HalCameraDeviceStatus>
+CameraDeviceStatus HalToFrameworkCameraDeviceStatus(
+ const HalCameraDeviceStatus& s) {
+ switch(s) {
+ case HalCameraDeviceStatus::PRESENT:
+ return CameraDeviceStatus::PRESENT;
+ case HalCameraDeviceStatus::NOT_PRESENT:
+ return CameraDeviceStatus::NOT_PRESENT;
+ case HalCameraDeviceStatus::ENUMERATING:
+ return CameraDeviceStatus::ENUMERATING;
+ }
+ ALOGW("Unexpectedcamera device status code %d", s);
+ return CameraDeviceStatus::NOT_PRESENT;
+}
+
+template <class HalCameraResourceCost>
+CameraResourceCost HalToFrameworkResourceCost(
+ const HalCameraResourceCost& s) {
+ CameraResourceCost internalResourceCost;
+ internalResourceCost.resourceCost = (uint32_t)s.resourceCost;
+ for (const auto device : s.conflictingDevices) {
+ internalResourceCost.conflictingDevices.emplace_back(device.c_str());
+ }
+ return internalResourceCost;
+}
+
+template <class HalTorchModeStatus>
+TorchModeStatus HalToFrameworkTorchModeStatus(
+ const HalTorchModeStatus& s) {
+ switch(s) {
+ case HalTorchModeStatus::NOT_AVAILABLE:
+ return TorchModeStatus::NOT_AVAILABLE;
+ case HalTorchModeStatus::AVAILABLE_OFF:
+ return TorchModeStatus::AVAILABLE_OFF;
+ case HalTorchModeStatus::AVAILABLE_ON:
+ return TorchModeStatus::AVAILABLE_ON;
+ }
+ ALOGW("Unexpectedcamera torch mode status code %d", s);
+ return TorchModeStatus::NOT_AVAILABLE;
+}
+
+template <class HalCameraDeviceStatus>
+ const char* HalDeviceStatusToString(const HalCameraDeviceStatus& s) {
+ switch(s) {
+ case HalCameraDeviceStatus::NOT_PRESENT:
+ return "NOT_PRESENT";
+ case HalCameraDeviceStatus::PRESENT:
+ return "PRESENT";
+ case HalCameraDeviceStatus::ENUMERATING:
+ return "ENUMERATING";
+ }
+ ALOGW("Unexpected HAL device status code %d", s);
+ return "UNKNOWN_STATUS";
+}
+
+}
+
+#endif
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
new file mode 100644
index 0000000..0922b74
--- /dev/null
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -0,0 +1,813 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "AidlProviderInfo.h"
+#include "common/HalConversionsTemplated.h"
+#include "common/CameraProviderInfoTemplated.h"
+
+#include <cutils/properties.h>
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android/binder_manager.h>
+#include <android/hardware/ICameraService.h>
+#include <camera_metadata_hidden.h>
+
+#include "device3/ZoomRatioMapper.h"
+#include <utils/SessionConfigurationUtils.h>
+#include <utils/Trace.h>
+
+namespace {
+const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
+} // anonymous namespace
+
+namespace android {
+
+namespace SessionConfigurationUtils = ::android::camera3::SessionConfigurationUtils;
+
+using namespace aidl::android::hardware;
+using namespace hardware::camera;
+using hardware::camera2::utils::CameraIdAndSessionConfiguration;
+using hardware::ICameraService;
+
+using HalDeviceStatusType = aidl::android::hardware::camera::common::CameraDeviceStatus;
+using ICameraProvider = aidl::android::hardware::camera::provider::ICameraProvider;
+using StatusListener = CameraProviderManager::StatusListener;
+
+status_t AidlProviderInfo::mapToStatusT(const ndk::ScopedAStatus& s) {
+ using Status = aidl::android::hardware::camera::common::Status;
+ Status st = static_cast<Status>(s.getServiceSpecificError());
+ switch(st) {
+ case Status::OK:
+ return OK;
+ case Status::ILLEGAL_ARGUMENT:
+ return BAD_VALUE;
+ case Status::CAMERA_IN_USE:
+ return -EBUSY;
+ case Status::MAX_CAMERAS_IN_USE:
+ return -EUSERS;
+ case Status::METHOD_NOT_SUPPORTED:
+ return UNKNOWN_TRANSACTION;
+ case Status::OPERATION_NOT_SUPPORTED:
+ return INVALID_OPERATION;
+ case Status::CAMERA_DISCONNECTED:
+ return DEAD_OBJECT;
+ case Status::INTERNAL_ERROR:
+ return INVALID_OPERATION;
+ }
+ ALOGW("Unexpected HAL status code %d", static_cast<int>(st));
+ return INVALID_OPERATION;
+}
+
+AidlProviderInfo::AidlProviderInfo(
+ const std::string &providerName,
+ const std::string &providerInstance,
+ CameraProviderManager *manager) :
+ CameraProviderManager::ProviderInfo(providerName, providerInstance, manager) {}
+
+status_t AidlProviderInfo::initializeAidlProvider(
+ std::shared_ptr<ICameraProvider>& interface, int64_t currentDeviceState) {
+
+ status_t res = parseProviderName(mProviderName, &mType, &mId);
+ if (res != OK) {
+ ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ ALOGI("Connecting to new camera provider: %s, isRemote? %d",
+ mProviderName.c_str(), interface->isRemote());
+
+ // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
+ // before setCallback returns
+ mCallbacks =
+ ndk::SharedRefBase::make<AidlProviderCallbacks>(this);
+ ndk::ScopedAStatus status =
+ interface->setCallback(mCallbacks);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
+ __FUNCTION__, mProviderName.c_str(), status.getMessage());
+ return mapToStatusT(status);
+ }
+
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(binderDied));
+ auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(), this);
+ if (link != STATUS_OK) {
+ ALOGW("%s: Unable to link to provider '%s' death notifications",
+ __FUNCTION__, mProviderName.c_str());
+ return DEAD_OBJECT;
+ }
+
+ if (!kEnableLazyHal) {
+ // Save HAL reference indefinitely
+ mSavedInterface = interface;
+ } else {
+ mActiveInterface = interface;
+ }
+
+ ALOGV("%s: Setting device state for %s: 0x%" PRIx64,
+ __FUNCTION__, mProviderName.c_str(), mDeviceState);
+ notifyDeviceStateChange(currentDeviceState);
+
+ res = setUpVendorTags();
+ if (res != OK) {
+ ALOGE("%s: Unable to set up vendor tags from provider '%s'",
+ __FUNCTION__, mProviderName.c_str());
+ return res;
+ }
+
+ // Get initial list of camera devices, if any
+ std::vector<std::string> devices;
+ std::vector<std::string> retDevices;
+ status = interface->getCameraIdList(&retDevices);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
+ __FUNCTION__, mProviderName.c_str(), status.getMessage());
+ return mapToStatusT(status);
+ }
+
+ for (auto& name : retDevices) {
+ uint16_t major, minor;
+ std::string type, id;
+ status_t res = parseDeviceName(name, &major, &minor, &type, &id);
+ if (res != OK) {
+ ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
+ return res;
+ } else {
+ devices.push_back(name);
+ mProviderPublicCameraIds.push_back(id);
+ }
+ }
+
+ // Get list of concurrent streaming camera device combinations
+ res = getConcurrentCameraIdsInternalLocked(interface);
+ if (res != OK) {
+ return res;
+ }
+
+ mSetTorchModeSupported = true;
+
+ mIsRemote = interface->isRemote();
+
+ initializeProviderInfoCommon(devices);
+ return OK;
+}
+
+void AidlProviderInfo::binderDied(void *cookie) {
+ AidlProviderInfo *provider = reinterpret_cast<AidlProviderInfo *>(cookie);
+ ALOGI("Camera provider '%s' has died; removing it", provider->mProviderInstance.c_str());
+ provider->mManager->removeProvider(provider->mProviderInstance);
+}
+
+status_t AidlProviderInfo::setUpVendorTags() {
+ if (mVendorTagDescriptor != nullptr)
+ return OK;
+
+ std::vector<camera::common::VendorTagSection> vts;
+ ::ndk::ScopedAStatus status;
+ const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+ status = interface->getVendorTags(&vts);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
+ __FUNCTION__, mProviderName.c_str(), status.getMessage());
+ return mapToStatusT(status);
+ }
+
+ // Read all vendor tag definitions into a descriptor
+ status_t res;
+ if ((res =
+ IdlVendorTagDescriptor::
+ createDescriptorFromIdl<std::vector<camera::common::VendorTagSection>,
+ camera::common::VendorTagSection>(vts, /*out*/mVendorTagDescriptor))
+ != 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 res;
+ }
+
+ return OK;
+}
+
+status_t AidlProviderInfo::notifyDeviceStateChange(int64_t newDeviceState) {
+
+ mDeviceState = newDeviceState;
+ // Check if the provider is currently active - not going to start it up for this notification
+ auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
+ if (interface != nullptr) {
+ // Send current device state
+ interface->notifyDeviceStateChange(mDeviceState);
+ }
+ return OK;
+}
+
+bool AidlProviderInfo::successfullyStartedProviderInterface() {
+ return startProviderInterface() != nullptr;
+}
+
+std::shared_ptr<camera::device::ICameraDevice>
+AidlProviderInfo::startDeviceInterface(const std::string &name) {
+ ::ndk::ScopedAStatus status;
+ std::shared_ptr<camera::device::ICameraDevice> cameraInterface;
+ const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
+ if (interface == nullptr) {
+ return nullptr;
+ }
+ status = interface->getCameraDeviceInterface(name, &cameraInterface);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
+ __FUNCTION__, name.c_str(), status.getMessage());
+ return nullptr;
+ }
+ return cameraInterface;
+}
+
+const std::shared_ptr<ICameraProvider> AidlProviderInfo::startProviderInterface() {
+ ATRACE_CALL();
+ ALOGV("Request to start camera provider: %s", mProviderName.c_str());
+ if (mSavedInterface != nullptr) {
+ return mSavedInterface;
+ }
+ if (!kEnableLazyHal) {
+ ALOGE("Bad provider state! Should not be here on a non-lazy HAL!");
+ return nullptr;
+ }
+
+ auto interface = mActiveInterface.lock();
+ if (interface == nullptr) {
+ // Try to get service without starting
+ interface =
+ ICameraProvider::fromBinder(
+ ndk::SpAIBinder(AServiceManager_checkService(mProviderName.c_str())));
+ if (interface == nullptr) {
+ ALOGV("Camera provider actually needs restart, calling getService(%s)",
+ mProviderName.c_str());
+ interface =
+ ICameraProvider::fromBinder(
+ ndk::SpAIBinder(
+ AServiceManager_getService(mProviderName.c_str())));
+
+ // Set all devices as ENUMERATING, provider should update status
+ // to PRESENT after initializing.
+ // This avoids failing getCameraDeviceInterface_V3_x before devices
+ // are ready.
+ for (auto& device : mDevices) {
+ device->mIsDeviceAvailable = false;
+ }
+
+ interface->setCallback(mCallbacks);
+ auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(),
+ this);
+ if (link != STATUS_OK) {
+ ALOGW("%s: Unable to link to provider '%s' death notifications",
+ __FUNCTION__, mProviderName.c_str());
+ mManager->removeProvider(mProviderName);
+ return nullptr;
+ }
+
+ // Send current device state
+ interface->notifyDeviceStateChange(mDeviceState);
+ }
+ mActiveInterface = interface;
+ } else {
+ ALOGV("Camera provider (%s) already in use. Re-using instance.",
+ mProviderName.c_str());
+ }
+
+ return interface;
+}
+
+::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::cameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ HalDeviceStatusType newStatus) {
+ sp<AidlProviderInfo> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: Parent provider not alive", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return parent->cameraDeviceStatusChange(cameraDeviceName, newStatus);
+}
+
+::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::torchModeStatusChange(
+ const std::string& cameraDeviceName,
+ aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
+ sp<AidlProviderInfo> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: Parent provider not alive", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return parent->torchModeStatusChange(cameraDeviceName, newStatus);
+
+};
+
+::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::physicalCameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ HalDeviceStatusType newStatus) {
+ sp<AidlProviderInfo> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: Parent provider not alive", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return parent->physicalCameraDeviceStatusChange(cameraDeviceName, physicalCameraDeviceName,
+ newStatus);
+};
+
+::ndk::ScopedAStatus AidlProviderInfo::cameraDeviceStatusChange(const std::string& cameraDeviceName,
+ HalDeviceStatusType newStatus) {
+ cameraDeviceStatusChangeInternal(cameraDeviceName, HalToFrameworkCameraDeviceStatus(newStatus));
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus AidlProviderInfo::torchModeStatusChange(const std::string& cameraDeviceName,
+ aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
+ torchModeStatusChangeInternal(cameraDeviceName, HalToFrameworkTorchModeStatus(newStatus));
+ return ::ndk::ScopedAStatus::ok();
+};
+
+::ndk::ScopedAStatus AidlProviderInfo::physicalCameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ HalDeviceStatusType newStatus) {
+ physicalCameraDeviceStatusChangeInternal(cameraDeviceName, physicalCameraDeviceName,
+ HalToFrameworkCameraDeviceStatus(newStatus));
+ return ::ndk::ScopedAStatus::ok();
+};
+
+std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
+ AidlProviderInfo::initializeDeviceInfo(
+ const std::string &name, const metadata_vendor_id_t tagId,
+ const std::string &id, uint16_t minorVersion) {
+ ::ndk::ScopedAStatus status;
+
+ auto cameraInterface = startDeviceInterface(name);
+ if (cameraInterface == nullptr) return nullptr;
+
+ camera::common::CameraResourceCost resourceCost;
+ status = cameraInterface->getResourceCost(&resourceCost);
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
+ name.c_str(), status.getMessage());
+ return nullptr;
+ }
+
+ for (auto& conflictName : resourceCost.conflictingDevices) {
+ uint16_t major, minor;
+ std::string type, id;
+ status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
+ if (res != OK) {
+ ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
+ return nullptr;
+ }
+ conflictName = id;
+ }
+
+ return std::unique_ptr<DeviceInfo3>(
+ new AidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
+ this, mProviderPublicCameraIds, cameraInterface));
+}
+
+status_t AidlProviderInfo::reCacheConcurrentStreamingCameraIdsLocked() {
+
+ // Check if the provider is currently active - not going to start it up for this notification
+ auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
+ if (interface == nullptr) {
+ ALOGE("%s: camera provider interface for %s is not valid", __FUNCTION__,
+ mProviderName.c_str());
+ return INVALID_OPERATION;
+ }
+
+ return getConcurrentCameraIdsInternalLocked(interface);
+}
+
+status_t AidlProviderInfo::getConcurrentCameraIdsInternalLocked(
+ std::shared_ptr<ICameraProvider> &interface) {
+ if (interface == nullptr) {
+ ALOGE("%s: null interface provided", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ std::vector<aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination> combs;
+ ::ndk::ScopedAStatus status = interface->getConcurrentCameraIds(&combs);
+
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error in getting concurrent camera ID list from provider '%s'",
+ __FUNCTION__, mProviderName.c_str());
+ return mapToStatusT(status);
+ }
+ mConcurrentCameraIdCombinations.clear();
+ for (const auto& combination : combs) {
+ std::unordered_set<std::string> deviceIds;
+ for (const auto &cameraDeviceId : combination.combination) {
+ deviceIds.insert(cameraDeviceId.c_str());
+ }
+ mConcurrentCameraIdCombinations.push_back(std::move(deviceIds));
+ }
+
+ return OK;
+}
+
+AidlProviderInfo::AidlDeviceInfo3::AidlDeviceInfo3(
+ const std::string& name,
+ const metadata_vendor_id_t tagId,
+ const std::string &id, uint16_t minorVersion,
+ const CameraResourceCost& resourceCost,
+ sp<CameraProviderManager::ProviderInfo> parentProvider,
+ const std::vector<std::string>& publicCameraIds,
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice> interface) :
+ DeviceInfo3(name, tagId, id, minorVersion, resourceCost, parentProvider, publicCameraIds) {
+
+ // Get camera characteristics and initialize flash unit availability
+ aidl::android::hardware::camera::device::CameraMetadata chars;
+ ::ndk::ScopedAStatus status = interface->getCameraCharacteristics(&chars);
+ std::vector<uint8_t> &metadata = chars.metadata;
+ camera_metadata_t *buffer = reinterpret_cast<camera_metadata_t*>(metadata.data());
+ size_t expectedSize = metadata.size();
+ int resV = validate_camera_metadata_structure(buffer, &expectedSize);
+ if (resV == OK || resV == CAMERA_METADATA_VALIDATION_SHIFTED) {
+ set_camera_metadata_vendor_id(buffer, mProviderTagid);
+ mCameraCharacteristics = buffer;
+ } else {
+ ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+ return;
+ }
+
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error getting camera characteristics for device %s"
+ " to check for a flash unit: %s", __FUNCTION__, id.c_str(),
+ status.getMessage());
+ return;
+ }
+
+ if (mCameraCharacteristics.exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
+ const auto &stateMap = mCameraCharacteristics.find(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
+ if ((stateMap.count > 0) && ((stateMap.count % 2) == 0)) {
+ for (size_t i = 0; i < stateMap.count; i += 2) {
+ mDeviceStateOrientationMap.emplace(stateMap.data.i64[i], stateMap.data.i64[i+1]);
+ }
+ } else {
+ ALOGW("%s: Invalid ANDROID_INFO_DEVICE_STATE_ORIENTATIONS map size: %zu", __FUNCTION__,
+ stateMap.count);
+ }
+ }
+
+ mSystemCameraKind = getSystemCameraKind();
+
+ status_t res = fixupMonochromeTags();
+ if (OK != res) {
+ ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return;
+ }
+ auto stat = addDynamicDepthTags();
+ if (OK != stat) {
+ ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-stat),
+ stat);
+ }
+ res = deriveHeicTags();
+ if (OK != res) {
+ ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+
+ if (camera3::SessionConfigurationUtils::isUltraHighResolutionSensor(mCameraCharacteristics)) {
+ status_t status = addDynamicDepthTags(/*maxResolution*/true);
+ if (OK != status) {
+ ALOGE("%s: Failed appending dynamic depth tags for maximum resolution mode: %s (%d)",
+ __FUNCTION__, strerror(-status), status);
+ }
+
+ status = deriveHeicTags(/*maxResolution*/true);
+ if (OK != status) {
+ ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities for"
+ "maximum resolution mode: %s (%d)", __FUNCTION__, strerror(-status), status);
+ }
+ }
+
+ res = addRotateCropTags();
+ if (OK != res) {
+ ALOGE("%s: Unable to add default SCALER_ROTATE_AND_CROP tags: %s (%d)", __FUNCTION__,
+ strerror(-res), res);
+ }
+ res = addPreCorrectionActiveArraySize();
+ if (OK != res) {
+ ALOGE("%s: Unable to add PRE_CORRECTION_ACTIVE_ARRAY_SIZE: %s (%d)", __FUNCTION__,
+ strerror(-res), res);
+ }
+ res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
+ &mCameraCharacteristics, &mSupportNativeZoomRatio);
+ if (OK != res) {
+ ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+
+ camera_metadata_entry flashAvailable =
+ mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
+ if (flashAvailable.count == 1 &&
+ flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
+ mHasFlashUnit = true;
+ } else {
+ mHasFlashUnit = false;
+ }
+
+ camera_metadata_entry entry =
+ mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
+ if (entry.count == 1) {
+ mTorchDefaultStrengthLevel = entry.data.i32[0];
+ } else {
+ mTorchDefaultStrengthLevel = 0;
+ }
+ entry = mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
+ if (entry.count == 1) {
+ mTorchMaximumStrengthLevel = entry.data.i32[0];
+ } else {
+ mTorchMaximumStrengthLevel = 0;
+ }
+
+ mTorchStrengthLevel = 0;
+
+ queryPhysicalCameraIds();
+
+ // Get physical camera characteristics if applicable
+ if (mIsLogicalCamera) {
+ for (auto& id : mPhysicalIds) {
+ if (std::find(mPublicCameraIds.begin(), mPublicCameraIds.end(), id) !=
+ mPublicCameraIds.end()) {
+ continue;
+ }
+
+ aidl::android::hardware::camera::device::CameraMetadata pChars;
+ status = interface->getPhysicalCameraCharacteristics(id, &pChars);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s",
+ __FUNCTION__, id.c_str(), id.c_str(), status.getMessage());
+ return;
+ }
+ std::vector<uint8_t> &pMetadata = pChars.metadata;
+ camera_metadata_t *pBuffer =
+ reinterpret_cast<camera_metadata_t*>(pMetadata.data());
+ size_t expectedSize = pMetadata.size();
+ int res = validate_camera_metadata_structure(pBuffer, &expectedSize);
+ if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
+ set_camera_metadata_vendor_id(pBuffer, mProviderTagid);
+ mPhysicalCameraCharacteristics[id] = pBuffer;
+ } else {
+ ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+ return;
+ }
+
+ res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
+ &mPhysicalCameraCharacteristics[id], &mSupportNativeZoomRatio);
+ if (OK != res) {
+ ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+ }
+ }
+
+ if (!kEnableLazyHal) {
+ // Save HAL reference indefinitely
+ mSavedInterface = interface;
+ }
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::setTorchMode(bool enabled) {
+ const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+ ::ndk::ScopedAStatus s = interface->setTorchMode(enabled);
+ if (!s.isOk()) {
+ ALOGE("%s Unable to set torch mode: %s", __FUNCTION__, s.getMessage());
+ return mapToStatusT(s);
+ }
+ return OK;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::turnOnTorchWithStrengthLevel(
+ int32_t torchStrength) {
+ const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ ::ndk::ScopedAStatus s = interface->turnOnTorchWithStrengthLevel(torchStrength);
+ if (!s.isOk()) {
+ ALOGE("%s Unable to set torch mode strength %d : %s", __FUNCTION__, torchStrength,
+ s.getMessage());
+ return mapToStatusT(s);
+ }
+ mTorchStrengthLevel = torchStrength;
+ return OK;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::getTorchStrengthLevel(int32_t *torchStrength) {
+ if (torchStrength == nullptr) {
+ return BAD_VALUE;
+ }
+ const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ ::ndk::ScopedAStatus status = interface->getTorchStrengthLevel(torchStrength);
+ if (!status.isOk()) {
+ ALOGE("%s: Couldn't get torch strength level: %s", __FUNCTION__, status.getMessage());
+ return mapToStatusT(status);
+ }
+ return OK;
+}
+
+std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+AidlProviderInfo::AidlDeviceInfo3::startDeviceInterface() {
+ Mutex::Autolock l(mDeviceAvailableLock);
+ std::shared_ptr<camera::device::ICameraDevice> device;
+ ATRACE_CALL();
+ if (mSavedInterface == nullptr) {
+ sp<AidlProviderInfo> parentProvider =
+ static_cast<AidlProviderInfo *>(mParentProvider.promote().get());
+ if (parentProvider != nullptr) {
+ // Wait for lazy HALs to confirm device availability
+ if (parentProvider->isExternalLazyHAL() && !mIsDeviceAvailable) {
+ ALOGV("%s: Wait for external device to become available %s",
+ __FUNCTION__,
+ mId.c_str());
+
+ auto res = mDeviceAvailableSignal.waitRelative(mDeviceAvailableLock,
+ kDeviceAvailableTimeout);
+ if (res != OK) {
+ ALOGE("%s: Failed waiting for device to become available",
+ __FUNCTION__);
+ return nullptr;
+ }
+ }
+
+ device = parentProvider->startDeviceInterface(mName);
+ }
+ } else {
+ device = mSavedInterface;
+ }
+ return device;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::dumpState(int fd) {
+ native_handle_t* handle = native_handle_create(1,0);
+ handle->data[0] = fd;
+ const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+ ::ndk::ScopedFileDescriptor sFd;
+ sFd.set(fcntl(fd, F_DUPFD_CLOEXEC, 0));
+ auto ret = interface->dumpState(sFd);
+ native_handle_delete(handle);
+ if (!ret.isOk()) {
+ return mapToStatusT(ret);
+ }
+ return OK;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::isSessionConfigurationSupported(
+ const SessionConfiguration &configuration, bool overrideForPerfClass, bool *status) {
+
+ camera::device::StreamConfiguration streamConfiguration;
+ bool earlyExit = false;
+ camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
+ CameraMetadata physicalChars;
+ getPhysicalCameraCharacteristics(id.c_str(), &physicalChars);
+ return physicalChars;
+ };
+ auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
+ String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
+ streamConfiguration, overrideForPerfClass, &earlyExit);
+
+ if (!bRes.isOk()) {
+ return UNKNOWN_ERROR;
+ }
+
+ if (earlyExit) {
+ *status = false;
+ return OK;
+ }
+
+ const std::shared_ptr<camera::device::ICameraDevice> interface =
+ startDeviceInterface();
+
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ ::ndk::ScopedAStatus ret =
+ interface->isStreamCombinationSupported(streamConfiguration, status);
+ if (!ret.isOk()) {
+ *status = false;
+ ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.getMessage());
+ return mapToStatusT(ret);
+ }
+ return OK;
+
+}
+
+status_t AidlProviderInfo::convertToAidlHALStreamCombinationAndCameraIdsLocked(
+ const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+ const std::set<std::string>& perfClassPrimaryCameraIds,
+ int targetSdkVersion,
+ std::vector<camera::provider::CameraIdAndStreamCombination>
+ *halCameraIdsAndStreamCombinations,
+ bool *earlyExit) {
+ binder::Status bStatus = binder::Status::ok();
+ std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamsV;
+ bool shouldExit = false;
+ status_t res = OK;
+ for (auto &cameraIdAndSessionConfig : cameraIdsAndSessionConfigs) {
+ const std::string& cameraId = cameraIdAndSessionConfig.mCameraId;
+ camera::device::StreamConfiguration streamConfiguration;
+ CameraMetadata deviceInfo;
+ bool overrideForPerfClass =
+ SessionConfigurationUtils::targetPerfClassPrimaryCamera(
+ perfClassPrimaryCameraIds, cameraId, targetSdkVersion);
+ res = mManager->getCameraCharacteristicsLocked(cameraId, overrideForPerfClass, &deviceInfo);
+ if (res != OK) {
+ return res;
+ }
+ camera3::metadataGetter getMetadata =
+ [this](const String8 &id, bool overrideForPerfClass) {
+ CameraMetadata physicalDeviceInfo;
+ mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
+ &physicalDeviceInfo);
+ return physicalDeviceInfo;
+ };
+ std::vector<std::string> physicalCameraIds;
+ mManager->isLogicalCameraLocked(cameraId, &physicalCameraIds);
+ bStatus =
+ SessionConfigurationUtils::convertToHALStreamCombination(
+ cameraIdAndSessionConfig.mSessionConfiguration,
+ String8(cameraId.c_str()), deviceInfo, getMetadata,
+ physicalCameraIds, streamConfiguration,
+ overrideForPerfClass, &shouldExit);
+ if (!bStatus.isOk()) {
+ ALOGE("%s: convertToHALStreamCombination failed", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if (shouldExit) {
+ *earlyExit = true;
+ return OK;
+ }
+ camera::provider::CameraIdAndStreamCombination halCameraIdAndStream;
+ halCameraIdAndStream.cameraId = cameraId;
+ halCameraIdAndStream.streamConfiguration = streamConfiguration;
+ halCameraIdsAndStreamsV.push_back(halCameraIdAndStream);
+ }
+ *halCameraIdsAndStreamCombinations = halCameraIdsAndStreamsV;
+ return OK;
+}
+
+status_t AidlProviderInfo::isConcurrentSessionConfigurationSupported(
+ const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+ const std::set<std::string>& perfClassPrimaryCameraIds,
+ int targetSdkVersion, bool *isSupported) {
+
+ std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamCombinations;
+ bool knowUnsupported = false;
+ status_t res = convertToAidlHALStreamCombinationAndCameraIdsLocked(
+ cameraIdsAndSessionConfigs, perfClassPrimaryCameraIds,
+ targetSdkVersion, &halCameraIdsAndStreamCombinations, &knowUnsupported);
+ if (res != OK) {
+ ALOGE("%s unable to convert session configurations provided to HAL stream"
+ "combinations", __FUNCTION__);
+ return res;
+ }
+ if (knowUnsupported) {
+ // We got to know the streams aren't valid before doing the HAL
+ // call itself.
+ *isSupported = false;
+ return OK;
+ }
+
+ // Check if the provider is currently active - not going to start it up for this notification
+ auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
+ if (interface == nullptr) {
+ // TODO: This might be some other problem
+ return INVALID_OPERATION;
+ }
+ ::ndk::ScopedAStatus status = interface->isConcurrentStreamCombinationSupported(
+ halCameraIdsAndStreamCombinations, isSupported);
+ if (!status.isOk()) {
+ *isSupported = false;
+ ALOGE("%s: hal interface session configuration query failed", __FUNCTION__);
+ return mapToStatusT(status);
+ }
+
+ return OK;
+}
+
+} //namespace android
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
new file mode 100644
index 0000000..aa71e85
--- /dev/null
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_AIDLPROVIDERINFOH
+#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_AIDLPROVIDERINFOH
+
+#include "common/CameraProviderManager.h"
+
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/provider/BnCameraProviderCallback.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
+
+namespace android {
+
+struct AidlProviderInfo : public CameraProviderManager::ProviderInfo {
+ // Current overall Android device physical status
+ int64_t mDeviceState;
+
+ // This pointer is used to keep a reference to the ICameraProvider that was last accessed.
+ std::weak_ptr<aidl::android::hardware::camera::provider::ICameraProvider> mActiveInterface;
+
+ std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider> mSavedInterface;
+
+ AidlProviderInfo(
+ const std::string &providerName,
+ const std::string &providerInstance,
+ CameraProviderManager *manager);
+
+ static status_t mapToStatusT(const ndk::ScopedAStatus& s);
+
+ // Start camera device interface, start the camera provider process for lazy
+ // hals, if needed
+ status_t initializeAidlProvider(
+ std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider>& interface,
+ int64_t currentDeviceState);
+
+ static void binderDied(void *cookie);
+
+ virtual IPCTransport getIPCTransport() override {return IPCTransport::AIDL;}
+
+ const std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider>
+ startProviderInterface();
+
+ virtual status_t setUpVendorTags() override;
+ virtual status_t notifyDeviceStateChange(int64_t newDeviceState) override;
+
+ virtual bool successfullyStartedProviderInterface() override;
+
+ virtual int64_t getDeviceState() override { return mDeviceState; };
+
+ /**
+ * Query the camera provider for concurrent stream configuration support
+ */
+ virtual status_t isConcurrentSessionConfigurationSupported(
+ const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+ const std::set<std::string>& perfClassPrimaryCameraIds,
+ int targetSdkVersion, bool *isSupported) override;
+
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+ startDeviceInterface(const std::string &deviceName);
+
+ // AIDL ICameraProviderCallback interface - these lock the parent
+ // mInterfaceMutex
+
+ ::ndk::ScopedAStatus cameraDeviceStatusChange(const std::string& cameraDeviceName,
+ ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus);
+
+ ::ndk::ScopedAStatus torchModeStatusChange(const std::string& cameraDeviceName,
+ ::aidl::android::hardware::camera::common::TorchModeStatus newStatus);
+
+ ::ndk::ScopedAStatus physicalCameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus);
+
+ struct AidlProviderCallbacks :
+ public aidl::android::hardware::camera::provider::BnCameraProviderCallback {
+ AidlProviderCallbacks(wp<AidlProviderInfo> parent) : mParent(parent) { }
+ virtual ::ndk::ScopedAStatus cameraDeviceStatusChange(const std::string& cameraDeviceName,
+ ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus) override;
+
+ virtual ::ndk::ScopedAStatus torchModeStatusChange(const std::string& cameraDeviceName,
+ ::aidl::android::hardware::camera::common::TorchModeStatus newStatus) override;
+
+ virtual ::ndk::ScopedAStatus physicalCameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus) override;
+
+ private:
+ wp<AidlProviderInfo> mParent = nullptr;
+
+ };
+
+ struct AidlDeviceInfo3 : public CameraProviderManager::ProviderInfo::DeviceInfo3 {
+
+ //TODO: fix init
+ const hardware::hidl_version mVersion = hardware::hidl_version{3, 2};
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+ mSavedInterface = nullptr;
+
+ AidlDeviceInfo3(const std::string& , const metadata_vendor_id_t ,
+ const std::string &, uint16_t ,
+ const CameraResourceCost& ,
+ sp<ProviderInfo> ,
+ const std::vector<std::string>& ,
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>);
+
+ ~AidlDeviceInfo3() {}
+
+ virtual status_t setTorchMode(bool enabled) override;
+ virtual status_t turnOnTorchWithStrengthLevel(int32_t torchStrength) override;
+ virtual status_t getTorchStrengthLevel(int32_t *torchStrength) override;
+
+ virtual status_t dumpState(int fd) override;
+
+ virtual status_t isSessionConfigurationSupported(
+ const SessionConfiguration &/*configuration*/,
+ bool overrideForPerfClass,
+ bool *status/*status*/);
+
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+ startDeviceInterface();
+ };
+
+ private:
+
+ // Helper for initializeDeviceInfo to use the right CameraProvider get method.
+ virtual std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &,
+ const metadata_vendor_id_t , const std::string &,
+ uint16_t ) override;
+
+ virtual status_t reCacheConcurrentStreamingCameraIdsLocked() override;
+
+ //Expects to have mLock locked
+
+ status_t getConcurrentCameraIdsInternalLocked(
+ std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider> &interface);
+
+ //expects to have mManager->mInterfaceMutex locked
+
+ status_t convertToAidlHALStreamCombinationAndCameraIdsLocked(
+ const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+ const std::set<std::string>& perfClassPrimaryCameraIds,
+ int targetSdkVersion,
+ std::vector<aidl::android::hardware::camera::provider::CameraIdAndStreamCombination>
+ *halCameraIdsAndStreamCombinations,
+ bool *earlyExit);
+ std::shared_ptr<AidlProviderCallbacks> mCallbacks = nullptr;
+ ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+
+};
+
+} // namespace android
+#endif
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index e8432a6..3c5ea75 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
#include "HidlProviderInfo.h"
+#include "common/HalConversionsTemplated.h"
+#include "common/CameraProviderInfoTemplated.h"
#include <cutils/properties.h>
@@ -42,6 +44,7 @@
using StatusListener = CameraProviderManager::StatusListener;
+using HalDeviceStatusType = android::hardware::camera::common::V1_0::CameraDeviceStatus;
using hardware::camera::provider::V2_5::DeviceState;
using hardware::ICameraService;
@@ -111,83 +114,6 @@
return "UNKNOWN_ERROR";
}
-static common::V1_0::CameraDeviceStatus mapToHidlCameraDeviceStatus(const CameraDeviceStatus& s) {
- switch(s) {
- case CameraDeviceStatus::PRESENT:
- return common::V1_0::CameraDeviceStatus::PRESENT;
- case CameraDeviceStatus::NOT_PRESENT:
- return common::V1_0::CameraDeviceStatus::NOT_PRESENT;
- case CameraDeviceStatus::ENUMERATING:
- return common::V1_0::CameraDeviceStatus::ENUMERATING;
- }
- ALOGW("Unexpectedcamera device status code %d", s);
- return common::V1_0::CameraDeviceStatus::NOT_PRESENT;
-}
-
-static CameraDeviceStatus hidlToInternalCameraDeviceStatus(
- const common::V1_0::CameraDeviceStatus& s) {
- switch(s) {
- case common::V1_0::CameraDeviceStatus::PRESENT:
- return CameraDeviceStatus::PRESENT;
- case common::V1_0::CameraDeviceStatus::NOT_PRESENT:
- return CameraDeviceStatus::NOT_PRESENT;
- case common::V1_0::CameraDeviceStatus::ENUMERATING:
- return CameraDeviceStatus::ENUMERATING;
- }
- ALOGW("Unexpectedcamera device status code %d", s);
- return CameraDeviceStatus::NOT_PRESENT;
-}
-
-static TorchModeStatus hidlToInternalTorchModeStatus(
- const common::V1_0::TorchModeStatus& s) {
- switch(s) {
- case common::V1_0::TorchModeStatus::NOT_AVAILABLE:
- return TorchModeStatus::NOT_AVAILABLE;
- case common::V1_0::TorchModeStatus::AVAILABLE_OFF:
- return TorchModeStatus::AVAILABLE_OFF;
- case common::V1_0::TorchModeStatus::AVAILABLE_ON:
- return TorchModeStatus::AVAILABLE_ON;
- }
- ALOGW("Unexpectedcamera torch mode status code %d", s);
- return TorchModeStatus::NOT_AVAILABLE;
-}
-
-static CameraResourceCost hidlToInternalResourceCost(
- const common::V1_0::CameraResourceCost& s) {
- CameraResourceCost internalResourceCost;
- internalResourceCost.resourceCost = s.resourceCost;
- for (const auto device : s.conflictingDevices) {
- internalResourceCost.conflictingDevices.emplace_back(device.c_str());
- }
- return internalResourceCost;
-}
-
-static const char* deviceStatusToString(const common::V1_0::CameraDeviceStatus& s) {
- switch(s) {
- case common::V1_0::CameraDeviceStatus::NOT_PRESENT:
- return "NOT_PRESENT";
- case common::V1_0::CameraDeviceStatus::PRESENT:
- return "PRESENT";
- case common::V1_0::CameraDeviceStatus::ENUMERATING:
- return "ENUMERATING";
- }
- ALOGW("Unexpected HAL device status code %d", s);
- return "UNKNOWN_STATUS";
-}
-
-static const char* torchStatusToString(const common::V1_0::TorchModeStatus& s) {
- switch(s) {
- case common::V1_0::TorchModeStatus::NOT_AVAILABLE:
- return "NOT_AVAILABLE";
- case common::V1_0::TorchModeStatus::AVAILABLE_OFF:
- return "AVAILABLE_OFF";
- case common::V1_0::TorchModeStatus::AVAILABLE_ON:
- return "AVAILABLE_ON";
- }
- ALOGW("Unexpected HAL torch mode status code %d", s);
- return "UNKNOWN_STATUS";
-}
-
status_t HidlProviderInfo::initializeHidlProvider(
sp<provider::V2_4::ICameraProvider>& interface,
int64_t currentDeviceState) {
@@ -326,55 +252,7 @@
mIsRemote = interface->isRemote();
- sp<StatusListener> listener = mManager->getStatusListener();
- for (auto& device : devices) {
- std::string id;
- status_t res = addDevice(device, common::V1_0::CameraDeviceStatus::PRESENT, &id);
- if (res != OK) {
- ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
- __FUNCTION__, device.c_str(), strerror(-res), res);
- continue;
- }
- }
-
- ALOGI("Camera provider %s ready with %zu camera devices",
- mProviderName.c_str(), mDevices.size());
-
- // Process cached status callbacks
- std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus =
- std::make_unique<std::vector<CameraStatusInfoT>>();
- {
- std::lock_guard<std::mutex> lock(mInitLock);
-
- for (auto& statusInfo : mCachedStatus) {
- std::string id, physicalId;
- status_t res = OK;
- if (statusInfo.isPhysicalCameraStatus) {
- res = physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
- statusInfo.cameraId, statusInfo.physicalCameraId,
- mapToHidlCameraDeviceStatus(statusInfo.status));
- } else {
- res = cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId,
- mapToHidlCameraDeviceStatus(statusInfo.status));
- }
- if (res == OK) {
- cachedStatus->emplace_back(statusInfo.isPhysicalCameraStatus,
- id.c_str(), physicalId.c_str(), statusInfo.status);
- }
- }
- mCachedStatus.clear();
-
- mInitialized = true;
- }
-
- // The cached status change callbacks cannot be fired directly from this
- // function, due to same-thread deadlock trying to acquire mInterfaceMutex
- // twice.
- if (listener != nullptr) {
- mInitialStatusCallbackFuture = std::async(std::launch::async,
- &CameraProviderManager::ProviderInfo::notifyInitialStatusChange, this,
- listener, std::move(cachedStatus));
- }
+ initializeProviderInfoCommon(devices);
return OK;
}
@@ -409,7 +287,10 @@
// Read all vendor tag definitions into a descriptor
status_t res;
- if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/mVendorTagDescriptor))
+ if ((res = IdlVendorTagDescriptor::createDescriptorFromIdl<
+ hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>,
+ hardware::camera::common::V1_0::VendorTagSection>(vts,
+ /*out*/mVendorTagDescriptor))
!= OK) {
ALOGE("%s: Could not generate descriptor from vendor tag operations,"
"received error %s (%d). Camera clients will not be able to use"
@@ -539,256 +420,25 @@
hardware::Return<void> HidlProviderInfo::cameraDeviceStatusChange(
const hardware::hidl_string& cameraDeviceName,
- hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
- sp<StatusListener> listener;
- std::string id;
- std::lock_guard<std::mutex> lock(mInitLock);
- CameraDeviceStatus internalNewStatus = hidlToInternalCameraDeviceStatus(newStatus);
- if (!mInitialized) {
- mCachedStatus.emplace_back(false /*isPhysicalCameraStatus*/,
- cameraDeviceName.c_str(), std::string().c_str(),
- internalNewStatus);
- return hardware::Void();
- }
-
- {
- std::lock_guard<std::mutex> lock(mLock);
- if (OK != cameraDeviceStatusChangeLocked(&id, cameraDeviceName, newStatus)) {
- return hardware::Void();
- }
- listener = mManager->getStatusListener();
- }
-
- // Call without lock held to allow reentrancy into provider manager
- if (listener != nullptr) {
- listener->onDeviceStatusChanged(String8(id.c_str()), internalNewStatus);
- }
-
+ HalDeviceStatusType newStatus) {
+ cameraDeviceStatusChangeInternal(cameraDeviceName, HalToFrameworkCameraDeviceStatus(newStatus));
return hardware::Void();
}
-status_t HidlProviderInfo::addDevice(const std::string& name,
- common::V1_0::CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
-
- ALOGI("Enumerating new camera device: %s", name.c_str());
-
- uint16_t major, minor;
- std::string type, id;
-
- status_t res = parseDeviceName(name, &major, &minor, &type, &id);
- if (res != OK) {
- return res;
- }
- if (type != mType) {
- ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
- type.c_str(), mType.c_str());
- return BAD_VALUE;
- }
- if (mManager->isValidDeviceLocked(id, major)) {
- ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
- name.c_str(), id.c_str(), major);
- return BAD_VALUE;
- }
-
- std::unique_ptr<DeviceInfo> deviceInfo;
- switch (major) {
- case 1:
- ALOGE("%s: Device %s: Unsupported HIDL device HAL major version %d:", __FUNCTION__,
- name.c_str(), major);
- return BAD_VALUE;
- case 3:
- deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
- break;
- default:
- ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
- name.c_str(), major);
- return BAD_VALUE;
- }
- if (deviceInfo == nullptr) return BAD_VALUE;
- deviceInfo->notifyDeviceStateChange(mDeviceState);
- deviceInfo->mStatus = hidlToInternalCameraDeviceStatus(initialStatus);
- bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
-
- mDevices.push_back(std::move(deviceInfo));
-
- mUniqueCameraIds.insert(id);
- if (isAPI1Compatible) {
- // addDevice can be called more than once for the same camera id if HAL
- // supports openLegacy.
- if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
- id) == mUniqueAPI1CompatibleCameraIds.end()) {
- mUniqueAPI1CompatibleCameraIds.push_back(id);
- }
- }
-
- if (parsedId != nullptr) {
- *parsedId = id;
- }
- return OK;
-}
-
-status_t HidlProviderInfo::cameraDeviceStatusChangeLocked(
- std::string* id, const hardware::hidl_string& cameraDeviceName,
- hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
- bool known = false;
- std::string cameraId;
- for (auto& deviceInfo : mDevices) {
- if (deviceInfo->mName == cameraDeviceName) {
- Mutex::Autolock l(deviceInfo->mDeviceAvailableLock);
- ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
- deviceStatusToString(newStatus),
- deviceStatusToString(mapToHidlCameraDeviceStatus(deviceInfo->mStatus)));
- deviceInfo->mStatus = hidlToInternalCameraDeviceStatus(newStatus);
- // TODO: Handle device removal (NOT_PRESENT)
- cameraId = deviceInfo->mId;
- known = true;
- deviceInfo->mIsDeviceAvailable =
- (newStatus == hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT);
- deviceInfo->mDeviceAvailableSignal.signal();
- break;
- }
- }
- // Previously unseen device; status must not be NOT_PRESENT
- if (!known) {
- if (newStatus == hardware::camera::common::V1_0::CameraDeviceStatus::NOT_PRESENT) {
- ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
- mProviderName.c_str(), cameraDeviceName.c_str());
- return BAD_VALUE;
- }
- addDevice(cameraDeviceName, newStatus, &cameraId);
- } else if (newStatus == hardware::camera::common::V1_0::CameraDeviceStatus::NOT_PRESENT) {
- removeDevice(cameraId);
- } else if (isExternalLazyHAL()) {
- // Do not notify CameraService for PRESENT->PRESENT (lazy HAL restart)
- // because NOT_AVAILABLE is set on CameraService::connect and a PRESENT
- // notif. would overwrite it
- return BAD_VALUE;
- }
- if (reCacheConcurrentStreamingCameraIdsLocked() != OK) {
- ALOGE("%s: CameraProvider %s could not re-cache concurrent streaming camera id list ",
- __FUNCTION__, mProviderName.c_str());
- }
- *id = cameraId;
- return OK;
-}
-
hardware::Return<void> HidlProviderInfo::physicalCameraDeviceStatusChange(
const hardware::hidl_string& cameraDeviceName,
const hardware::hidl_string& physicalCameraDeviceName,
- hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
- sp<StatusListener> listener;
- std::string id;
- std::string physicalId;
- std::lock_guard<std::mutex> lock(mInitLock);
- CameraDeviceStatus newInternalStatus = hidlToInternalCameraDeviceStatus(newStatus);
- if (!mInitialized) {
- mCachedStatus.emplace_back(true /*isPhysicalCameraStatus*/, cameraDeviceName,
- physicalCameraDeviceName, newInternalStatus);
- return hardware::Void();
- }
-
- {
- std::lock_guard<std::mutex> lock(mLock);
-
- if (OK != physicalCameraDeviceStatusChangeLocked(&id, &physicalId, cameraDeviceName,
- physicalCameraDeviceName, newStatus)) {
- return hardware::Void();
- }
-
- listener = mManager->getStatusListener();
- }
- // Call without lock held to allow reentrancy into provider manager
- if (listener != nullptr) {
- listener->onDeviceStatusChanged(String8(id.c_str()),
- String8(physicalId.c_str()), newInternalStatus);
- }
+ HalDeviceStatusType newStatus) {
+ physicalCameraDeviceStatusChangeInternal(cameraDeviceName, physicalCameraDeviceName,
+ HalToFrameworkCameraDeviceStatus(newStatus));
return hardware::Void();
}
-status_t HidlProviderInfo::physicalCameraDeviceStatusChangeLocked(
- std::string* id, std::string* physicalId,
- const hardware::hidl_string& cameraDeviceName,
- const hardware::hidl_string& physicalCameraDeviceName,
- hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
- bool known = false;
- std::string cameraId;
- for (auto& deviceInfo : mDevices) {
- if (deviceInfo->mName == cameraDeviceName) {
- cameraId = deviceInfo->mId;
- if (!deviceInfo->mIsLogicalCamera) {
- ALOGE("%s: Invalid combination of camera id %s, physical id %s",
- __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
- return BAD_VALUE;
- }
- if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
- physicalCameraDeviceName) == deviceInfo->mPhysicalIds.end()) {
- ALOGE("%s: Invalid combination of camera id %s, physical id %s",
- __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
- return BAD_VALUE;
- }
- ALOGI("Camera device %s physical device %s status is now %s",
- cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(),
- deviceStatusToString(newStatus));
- known = true;
- break;
- }
- }
- // Previously unseen device; status must not be NOT_PRESENT
- if (!known) {
- ALOGW("Camera provider %s says an unknown camera device %s-%s is not present. Curious.",
- mProviderName.c_str(), cameraDeviceName.c_str(),
- physicalCameraDeviceName.c_str());
- return BAD_VALUE;
- }
-
- *id = cameraId;
- *physicalId = physicalCameraDeviceName.c_str();
- return OK;
-}
-
hardware::Return<void> HidlProviderInfo::torchModeStatusChange(
const hardware::hidl_string& cameraDeviceName,
hardware::camera::common::V1_0::TorchModeStatus newStatus) {
- sp<StatusListener> listener;
- SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
- std::string id;
- bool known = false;
- {
- // Hold mLock for accessing mDevices
- std::lock_guard<std::mutex> lock(mLock);
- for (auto& deviceInfo : mDevices) {
- if (deviceInfo->mName == cameraDeviceName) {
- ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
- torchStatusToString(newStatus));
- id = deviceInfo->mId;
- known = true;
- systemCameraKind = deviceInfo->mSystemCameraKind;
- if (hardware::camera::common::V1_0::TorchModeStatus::AVAILABLE_ON != newStatus) {
- mManager->removeRef(CameraProviderManager::DeviceMode::TORCH, id);
- }
- break;
- }
- }
- if (!known) {
- ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
- mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
- return hardware::Void();
- }
- // no lock needed since listener is set up only once during
- // CameraProviderManager initialization and then never changed till it is
- // destructed.
- listener = mManager->getStatusListener();
- }
- // Call without lock held to allow reentrancy into provider manager
- // The problem with holding mLock here is that we
- // might be limiting re-entrancy : CameraService::onTorchStatusChanged calls
- // back into CameraProviderManager which might try to hold mLock again (eg:
- // findDeviceInfo, which should be holding mLock while iterating through
- // each provider's devices).
- if (listener != nullptr) {
- listener->onTorchStatusChanged(String8(id.c_str()),
- hidlToInternalTorchModeStatus(newStatus), systemCameraKind);
- }
+
+ torchModeStatusChangeInternal(cameraDeviceName, HalToFrameworkTorchModeStatus(newStatus));
return hardware::Void();
}
@@ -836,7 +486,7 @@
}
return std::unique_ptr<DeviceInfo3>(
- new HidlDeviceInfo3(name, tagId, id, minorVersion, hidlToInternalResourceCost(resourceCost),
+ new HidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
this, mProviderPublicCameraIds, cameraInterface));
}
@@ -1474,91 +1124,4 @@
return INVALID_OPERATION;
}
-status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
- const hardware::hidl_vec<common::V1_0::VendorTagSection>& vts,
- sp<VendorTagDescriptor>& descriptor) {
-
- int tagCount = 0;
-
- for (size_t s = 0; s < vts.size(); s++) {
- tagCount += vts[s].tags.size();
- }
-
- if (tagCount < 0 || tagCount > INT32_MAX) {
- ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
- return BAD_VALUE;
- }
-
- Vector<uint32_t> tagArray;
- LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
- "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
-
-
- sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
- desc->mTagCount = tagCount;
-
- SortedVector<String8> sections;
- KeyedVector<uint32_t, String8> tagToSectionMap;
-
- int idx = 0;
- for (size_t s = 0; s < vts.size(); s++) {
- const common::V1_0::VendorTagSection& section = vts[s];
- const char *sectionName = section.sectionName.c_str();
- if (sectionName == NULL) {
- ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
- return BAD_VALUE;
- }
- String8 sectionString(sectionName);
- sections.add(sectionString);
-
- for (size_t j = 0; j < section.tags.size(); j++) {
- uint32_t tag = section.tags[j].tagId;
- if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
- ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
- return BAD_VALUE;
- }
-
- tagArray.editItemAt(idx++) = section.tags[j].tagId;
-
- const char *tagName = section.tags[j].tagName.c_str();
- if (tagName == NULL) {
- ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
- return BAD_VALUE;
- }
- desc->mTagToNameMap.add(tag, String8(tagName));
- tagToSectionMap.add(tag, sectionString);
-
- int tagType = (int) section.tags[j].tagType;
- if (tagType < 0 || tagType >= NUM_TYPES) {
- ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
- return BAD_VALUE;
- }
- desc->mTagToTypeMap.add(tag, tagType);
- }
- }
-
- desc->mSections = sections;
-
- for (size_t i = 0; i < tagArray.size(); ++i) {
- uint32_t tag = tagArray[i];
- String8 sectionString = tagToSectionMap.valueFor(tag);
-
- // Set up tag to section index map
- ssize_t index = sections.indexOf(sectionString);
- LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
- desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
-
- // Set up reverse mapping
- ssize_t reverseIndex = -1;
- if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
- KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
- reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
- }
- desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
- }
-
- descriptor = std::move(desc);
- return OK;
-}
-
} //namespace android
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
index 0ba2aff..4181fea 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
@@ -21,25 +21,6 @@
namespace android {
-/**
- * The vendor tag descriptor class that takes HIDL vendor tag information as
- * input. Not part of VendorTagDescriptor class because that class is used
- * in AIDL generated sources which don't have access to HIDL headers.
- */
-class HidlVendorTagDescriptor : public VendorTagDescriptor {
-public:
- /**
- * Create a VendorTagDescriptor object from the HIDL VendorTagSection
- * vector.
- *
- * Returns OK on success, or a negative error code.
- */
- static status_t createDescriptorFromHidl(
- const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
- /*out*/
- sp<VendorTagDescriptor>& descriptor);
-};
-
struct HidlProviderInfo : public CameraProviderManager::ProviderInfo,
virtual public hardware::camera::provider::V2_6::ICameraProviderCallback,
virtual public hardware::hidl_death_recipient {
@@ -70,6 +51,8 @@
virtual bool successfullyStartedProviderInterface() override;
+ virtual int64_t getDeviceState() override {return mDeviceState;};
+
virtual status_t setUpVendorTags() override;
virtual status_t notifyDeviceStateChange(int64_t) override;
@@ -129,24 +112,10 @@
private:
- status_t cameraDeviceStatusChangeLocked(
- std::string* , const hardware::hidl_string& ,
- hardware::camera::common::V1_0::CameraDeviceStatus );
-
- status_t physicalCameraDeviceStatusChangeLocked(
- std::string* , std::string* ,
- const hardware::hidl_string& ,
- const hardware::hidl_string& ,
- hardware::camera::common::V1_0::CameraDeviceStatus );
-
- status_t addDevice(const std::string& ,
- hardware::camera::common::V1_0::CameraDeviceStatus ,
- /*out*/ std::string *);
-
- std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &,
+ virtual std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &,
const metadata_vendor_id_t , const std::string &,
- uint16_t );
- status_t reCacheConcurrentStreamingCameraIdsLocked();
+ uint16_t ) override;
+ virtual status_t reCacheConcurrentStreamingCameraIdsLocked() override;
//Expects to have mLock locked
status_t getConcurrentCameraIdsInternalLocked(