Camera: Support querying session config with parameters
Existing isSessionConfigurationSupported doesn't consider session
parameters. However, many features are modeled as a session parameters.
Add a new API to query session configuration support considring session
parameters.
Test: Camera CTS
Bug: 309627704
Change-Id: If64d878cb0052c0f78db277ebe605d36197eb618
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 01199af..983b2c1 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -35,6 +35,7 @@
#include "binder/Status.h"
#include "FrameProducer.h"
#include "utils/IPCTransport.h"
+#include "utils/SessionConfigurationUtils.h"
#include "CameraOfflineSessionBase.h"
@@ -42,17 +43,6 @@
namespace camera3 {
-typedef enum camera_request_template {
- CAMERA_TEMPLATE_PREVIEW = 1,
- CAMERA_TEMPLATE_STILL_CAPTURE = 2,
- CAMERA_TEMPLATE_VIDEO_RECORD = 3,
- CAMERA_TEMPLATE_VIDEO_SNAPSHOT = 4,
- CAMERA_TEMPLATE_ZERO_SHUTTER_LAG = 5,
- CAMERA_TEMPLATE_MANUAL = 6,
- CAMERA_TEMPLATE_COUNT,
- CAMERA_VENDOR_TEMPLATE_START = 0x40000000
-} camera_request_template_t;
-
typedef enum camera_stream_configuration_mode {
CAMERA_STREAM_CONFIGURATION_NORMAL_MODE = 0,
CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE = 1,
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index adcb523..fbb5e1b 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -397,7 +397,7 @@
status_t CameraProviderManager::isSessionConfigurationSupported(const std::string& id,
const SessionConfiguration &configuration, bool overrideForPerfClass,
- metadataGetter getMetadata, bool *status /*out*/) const {
+ bool checkSessionParams, bool *status /*out*/) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo == nullptr) {
@@ -405,7 +405,41 @@
}
return deviceInfo->isSessionConfigurationSupported(configuration,
- overrideForPerfClass, getMetadata, status);
+ overrideForPerfClass, checkSessionParams, status);
+}
+
+status_t CameraProviderManager::createDefaultRequest(const std::string& cameraId,
+ camera_request_template_t templateId,
+ CameraMetadata* metadata) const {
+ ATRACE_CALL();
+ if (templateId <= 0 || templateId >= CAMERA_TEMPLATE_COUNT) {
+ return BAD_VALUE;
+ }
+
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+ auto deviceInfo = findDeviceInfoLocked(cameraId);
+ if (deviceInfo == nullptr) {
+ return NAME_NOT_FOUND;
+ }
+
+ camera_metadata_t *rawRequest;
+ status_t res = deviceInfo->createDefaultRequest(templateId,
+ &rawRequest);
+
+ if (res == BAD_VALUE) {
+ ALOGI("%s: template %d is not supported on this camera device",
+ __FUNCTION__, templateId);
+ return res;
+ } else if (res != OK) {
+ ALOGE("Unable to construct request template %d: %s (%d)",
+ templateId, strerror(-res), res);
+ return res;
+ }
+
+ set_camera_metadata_vendor_id(rawRequest, deviceInfo->mProviderTagid);
+ metadata->acquire(rawRequest);
+
+ return OK;
}
status_t CameraProviderManager::getCameraIdIPCTransport(const std::string &id,
@@ -1011,6 +1045,20 @@
}
}
+CameraMetadata CameraProviderManager::ProviderInfo::DeviceInfo3::deviceInfo(
+ const std::string &id) {
+ if (id.empty()) {
+ return mCameraCharacteristics;
+ } else {
+ if (mPhysicalCameraCharacteristics.find(id) != mPhysicalCameraCharacteristics.end()) {
+ return mPhysicalCameraCharacteristics.at(id);
+ } else {
+ ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, id.c_str());
+ return mCameraCharacteristics;
+ }
+ }
+}
+
SystemCameraKind CameraProviderManager::ProviderInfo::DeviceInfo3::getSystemCameraKind() {
camera_metadata_entry_t entryCap;
entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
@@ -1757,6 +1805,26 @@
return res;
}
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addSessionConfigQueryVersionTag() {
+ sp<ProviderInfo> parentProvider = mParentProvider.promote();
+ if (parentProvider == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ int versionCode = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_UPSIDE_DOWN_CAKE;
+ IPCTransport ipcTransport = parentProvider->getIPCTransport();
+ int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
+ if (ipcTransport == IPCTransport::AIDL
+ && deviceVersion >= CAMERA_DEVICE_API_VERSION_1_3) {
+ versionCode = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_VANILLA_ICE_CREAM;
+ }
+
+ auto& c = mCameraCharacteristics;
+ status_t res = c.update(ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION, &versionCode, 1);
+
+ return res;
+}
+
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::removeAvailableKeys(
CameraMetadata& c, const std::vector<uint32_t>& keys, uint32_t keyTag) {
status_t res = OK;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index fd04854..6142a71 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -87,6 +87,7 @@
#define CAMERA_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0)
#define CAMERA_DEVICE_API_VERSION_1_2 HARDWARE_DEVICE_API_VERSION(1, 2)
+#define CAMERA_DEVICE_API_VERSION_1_3 HARDWARE_DEVICE_API_VERSION(1, 3)
#define CAMERA_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0)
#define CAMERA_DEVICE_API_VERSION_3_1 HARDWARE_DEVICE_API_VERSION(3, 1)
#define CAMERA_DEVICE_API_VERSION_3_2 HARDWARE_DEVICE_API_VERSION(3, 2)
@@ -299,12 +300,20 @@
int targetSdkVersion, bool *isSupported);
std::vector<std::unordered_set<std::string>> getConcurrentCameraIds() const;
+
+ /**
+ * Create a default capture request metadata for a camera and a specific
+ * template.
+ */
+ status_t createDefaultRequest(const std::string& id,
+ camera3::camera_request_template_t templateId,
+ hardware::camera2::impl::CameraMetadataNative* request) const;
/**
* Check for device support of specific stream combination.
*/
status_t isSessionConfigurationSupported(const std::string& id,
const SessionConfiguration &configuration,
- bool overrideForPerfClass, camera3::metadataGetter getMetadata,
+ bool overrideForPerfClass, bool checkSessionParams,
bool *status /*out*/) const;
/**
@@ -619,12 +628,17 @@
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &/*configuration*/,
bool /*overrideForPerfClass*/,
- camera3::metadataGetter /*getMetadata*/,
+ bool /*checkSessionParams*/,
bool * /*status*/) {
return INVALID_OPERATION;
}
virtual status_t filterSmallJpegSizes() = 0;
virtual void notifyDeviceStateChange(int64_t /*newState*/) {}
+ virtual status_t createDefaultRequest(
+ camera3::camera_request_template_t /*templateId*/,
+ camera_metadata_t** /*metadata*/) {
+ return INVALID_OPERATION;
+ }
DeviceInfo(const std::string& name, const metadata_vendor_id_t tagId,
const std::string &id, const hardware::hidl_version& version,
@@ -675,10 +689,6 @@
bool overrideToPortrait) override;
virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
CameraMetadata *characteristics) const override;
- virtual status_t isSessionConfigurationSupported(
- const SessionConfiguration &configuration, bool /*overrideForPerfClass*/,
- camera3::metadataGetter /*getMetadata*/,
- bool *status /*out*/) = 0;
virtual status_t filterSmallJpegSizes() override;
virtual void notifyDeviceStateChange(
int64_t newState) override;
@@ -712,6 +722,7 @@
status_t addAutoframingTags();
status_t addPreCorrectionActiveArraySize();
status_t addReadoutTimestampTag(bool readoutTimestampSupported = true);
+ status_t addSessionConfigQueryVersionTag();
static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag,
android_pixel_format_t format,
@@ -736,6 +747,8 @@
std::vector<int64_t>* stallDurations,
const camera_metadata_entry& halStreamConfigs,
const camera_metadata_entry& halStreamDurations);
+
+ CameraMetadata deviceInfo(const std::string &id);
};
protected:
std::string mType;
@@ -887,8 +900,6 @@
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);
static bool isVirtualCameraHalEnabled();
};
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index c2b8bf4..a64c9d7 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -386,7 +386,7 @@
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) {
+ const std::string &id, uint16_t /*minorVersion*/) {
::ndk::ScopedAStatus status;
auto cameraInterface = startDeviceInterface(name);
@@ -411,9 +411,18 @@
conflictName = id;
}
+ int32_t interfaceVersion = 0;
+ status = cameraInterface->getInterfaceVersion(&interfaceVersion);
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to obtain interface version for camera device %s: %s", __FUNCTION__,
+ id.c_str(), status.getMessage());
+ return nullptr;
+ }
+
return std::unique_ptr<DeviceInfo3>(
- new AidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
- this, mProviderPublicCameraIds, cameraInterface));
+ new AidlDeviceInfo3(name, tagId, id, static_cast<uint16_t>(interfaceVersion),
+ HalToFrameworkResourceCost(resourceCost), this,
+ mProviderPublicCameraIds, cameraInterface));
}
status_t AidlProviderInfo::reCacheConcurrentStreamingCameraIdsLocked() {
@@ -604,6 +613,14 @@
mHasFlashUnit = false;
}
+ if (flags::feature_combination_query()) {
+ res = addSessionConfigQueryVersionTag();
+ if (OK != res) {
+ ALOGE("%s: Unable to add sessionConfigurationQueryVersion tag: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+ }
+
camera_metadata_entry entry =
mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
if (entry.count == 1) {
@@ -766,13 +783,24 @@
status_t AidlProviderInfo::AidlDeviceInfo3::isSessionConfigurationSupported(
const SessionConfiguration &configuration, bool overrideForPerfClass,
- camera3::metadataGetter getMetadata, bool *status) {
+ bool checkSessionParams, bool *status) {
+
+ auto operatingMode = configuration.getOperatingMode();
+
+ auto res = SessionConfigurationUtils::checkOperatingMode(operatingMode,
+ mCameraCharacteristics, mId);
+ if (!res.isOk()) {
+ return UNKNOWN_ERROR;
+ }
camera::device::StreamConfiguration streamConfiguration;
bool earlyExit = false;
+ camera3::metadataGetter getMetadata = [this](const std::string &id,
+ bool /*overrideForPerfClass*/) {return this->deviceInfo(id);};
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
mId, mCameraCharacteristics, mCompositeJpegRDisabled, getMetadata,
- mPhysicalIds, streamConfiguration, overrideForPerfClass, &earlyExit);
+ mPhysicalIds, streamConfiguration, overrideForPerfClass, mProviderTagid,
+ checkSessionParams, &earlyExit);
if (!bRes.isOk()) {
return UNKNOWN_ERROR;
@@ -790,8 +818,25 @@
return DEAD_OBJECT;
}
- ::ndk::ScopedAStatus ret =
- interface->isStreamCombinationSupported(streamConfiguration, status);
+ ::ndk::ScopedAStatus ret;
+ if (checkSessionParams) {
+ // Only interface version 1_3 or greater supports
+ // isStreamCombinationWIthSettingsSupported.
+ int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_1_3) {
+ ALOGI("%s: Camera device version (major %d, minor %d) doesn't support querying of "
+ "session configuration!", __FUNCTION__, mVersion.get_major(),
+ mVersion.get_minor());
+ return INVALID_OPERATION;
+ }
+ if (flags::feature_combination_query()) {
+ ret = interface->isStreamCombinationWithSettingsSupported(streamConfiguration, status);
+ } else {
+ return INVALID_OPERATION;
+ }
+ } else {
+ ret = interface->isStreamCombinationSupported(streamConfiguration, status);
+ }
if (!ret.isOk()) {
*status = false;
ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.getMessage());
@@ -801,6 +846,60 @@
}
+status_t AidlProviderInfo::AidlDeviceInfo3::createDefaultRequest(
+ camera3::camera_request_template_t templateId, camera_metadata_t** metadata) {
+ const std::shared_ptr<camera::device::ICameraDevice> interface =
+ startDeviceInterface();
+
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_1_3) {
+ ALOGI("%s: Camera device minor version 0x%x doesn't support creating "
+ " default request!", __FUNCTION__, mVersion.get_minor());
+ return INVALID_OPERATION;
+ }
+
+ aidl::android::hardware::camera::device::CameraMetadata request;
+
+ using aidl::android::hardware::camera::device::RequestTemplate;
+ RequestTemplate id;
+ status_t res = SessionConfigurationUtils::mapRequestTemplateToAidl(
+ templateId, &id);
+ if (res != OK) {
+ return res;
+ }
+
+ if (!flags::feature_combination_query()) {
+ return INVALID_OPERATION;
+ }
+
+ auto err = interface->constructDefaultRequestSettings(id, &request);
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
+ return AidlProviderInfo::mapToStatusT(err);
+ }
+ const camera_metadata *r =
+ reinterpret_cast<const camera_metadata_t*>(request.metadata.data());
+ size_t expectedSize = request.metadata.size();
+ int ret = validate_camera_metadata_structure(r, &expectedSize);
+ if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
+ *metadata = clone_camera_metadata(r);
+ if (*metadata == nullptr) {
+ ALOGE("%s: Unable to clone camera metadata received from HAL",
+ __FUNCTION__);
+ res = UNKNOWN_ERROR;
+ }
+ } else {
+ ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+ res = UNKNOWN_ERROR;
+ }
+
+ return res;
+}
+
status_t AidlProviderInfo::convertToAidlHALStreamCombinationAndCameraIdsLocked(
const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
const std::set<std::string>& perfClassPrimaryCameraIds,
@@ -840,7 +939,8 @@
cameraId, deviceInfo,
mManager->isCompositeJpegRDisabledLocked(cameraId), getMetadata,
physicalCameraIds, streamConfiguration,
- overrideForPerfClass, &shouldExit);
+ overrideForPerfClass, mProviderTagid,
+ /*checkSessionParams*/false, &shouldExit);
if (!bStatus.isOk()) {
ALOGE("%s: convertToHALStreamCombination failed", __FUNCTION__);
return INVALID_OPERATION;
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
index 90bc627..cc5101a 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
@@ -107,8 +107,6 @@
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;
@@ -129,9 +127,13 @@
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &/*configuration*/,
- bool overrideForPerfClass, camera3::metadataGetter /*getMetadata*/,
+ bool overrideForPerfClass, bool checkSessionParams,
bool *status/*status*/);
+ virtual status_t createDefaultRequest(
+ camera3::camera_request_template_t templateId,
+ camera_metadata_t** metadata) override;
+
std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
startDeviceInterface();
};
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index e4bd503..d2643c1 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -853,13 +853,21 @@
status_t HidlProviderInfo::HidlDeviceInfo3::isSessionConfigurationSupported(
const SessionConfiguration &configuration, bool overrideForPerfClass,
- metadataGetter getMetadata, bool *status) {
+ bool checkSessionParams, bool *status) {
+
+ if (checkSessionParams) {
+ // HIDL device doesn't support checking session parameters
+ return INVALID_OPERATION;
+ }
hardware::camera::device::V3_7::StreamConfiguration configuration_3_7;
bool earlyExit = false;
+ camera3::metadataGetter getMetadata = [this](const std::string &id,
+ bool /*overrideForPerfClass*/) {return this->deviceInfo(id);};
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
mId, mCameraCharacteristics, getMetadata, mPhysicalIds,
- configuration_3_7, overrideForPerfClass, &earlyExit);
+ configuration_3_7, overrideForPerfClass, mProviderTagid,
+ &earlyExit);
if (!bRes.isOk()) {
return UNKNOWN_ERROR;
@@ -961,7 +969,7 @@
cameraIdAndSessionConfig.mSessionConfiguration,
cameraId, deviceInfo, getMetadata,
physicalCameraIds, streamConfiguration,
- overrideForPerfClass, &shouldExit);
+ overrideForPerfClass, mProviderTagid, &shouldExit);
if (!bStatus.isOk()) {
ALOGE("%s: convertToHALStreamCombination failed", __FUNCTION__);
return INVALID_OPERATION;
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
index fa6f4d4..f53db7f 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
@@ -105,7 +105,7 @@
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &/*configuration*/,
- bool overrideForPerfClass, camera3::metadataGetter getMetadata,
+ bool overrideForPerfClass, bool checkSessionParams,
bool *status/*status*/);
sp<hardware::camera::device::V3_2::ICameraDevice> startDeviceInterface();
};