Add FMQ support to camera2 SDK for metadata transfer
This CL adds support for CaptureResult metadata to be transferred over
FMQ instead of binder copies.
Bug: 362791857
Flag: com.android.internal.camera.flags.fmq_metadata
Test: GCA
Test: Perfetto profiling shows decreased cameraserver to client
onResultReceived latency
Change-Id: Ia8df1a4cef5008c06dc2ca4fdd319704d5e049ab
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index b9c8206..b44f949 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -87,7 +87,9 @@
"android.hardware.camera.device@3.6",
"android.hardware.camera.device@3.7",
"android.hardware.common-V2-ndk",
+ "android.hardware.common-V2-cpp",
"android.hardware.common.fmq-V1-ndk",
+ "android.hardware.common.fmq-V1-cpp",
"camera_platform_flags_c_lib",
"com.android.window.flags.window-aconfig_flags_c_lib",
"media_permission-aidl-cpp",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 31a45c3..fdb5b7d 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1492,6 +1492,7 @@
int servicePid, std::pair<int, IPCTransport> deviceVersionAndTransport,
apiLevel effectiveApiLevel, bool overrideForPerfClass, int rotationOverride,
bool forceSlowJpegMode, const std::string& originalCameraId, bool sharedMode,
+ bool isVendorClient,
/*out*/sp<BasicClient>* client) {
// For HIDL devices
if (deviceVersionAndTransport.second == IPCTransport::HIDL) {
@@ -1537,7 +1538,8 @@
cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
cameraService->mAttributionAndPermissionUtils, clientAttribution, callingPid,
systemNativeClient, cameraId, facing, sensorOrientation, servicePid,
- overrideForPerfClass, rotationOverride, originalCameraId, sharedMode);
+ overrideForPerfClass, rotationOverride, originalCameraId, sharedMode,
+ isVendorClient);
ALOGI("%s: Camera2 API, rotationOverride %d", __FUNCTION__, rotationOverride);
}
return Status::ok();
@@ -1638,7 +1640,7 @@
/*rotationOverride*/
hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT,
/*forceSlowJpegMode*/ false, cameraIdStr, /*isNonSystemNdk*/ false,
- /*sharedMode*/false, /*out*/ tmp))
+ /*sharedMode*/false, /*isVendorClient*/false,/*out*/ tmp))
.isOk()) {
ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().c_str());
}
@@ -2202,7 +2204,8 @@
cameraClient, cameraIdStr, api1CameraId, resolvedClientAttribution,
/*systemNativeClient*/ false, API_1,
/*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion, rotationOverride,
- forceSlowJpegMode, cameraIdStr, isNonSystemNdk, /*sharedMode*/false, /*out*/ client);
+ forceSlowJpegMode, cameraIdStr, isNonSystemNdk, /*sharedMode*/false,
+ /*isVendorClient*/ false, /*out*/ client);
if (!ret.isOk()) {
logRejected(cameraIdStr, getCallingPid(),
@@ -2286,7 +2289,32 @@
const std::string& unresolvedCameraId,
int oomScoreOffset, int targetSdkVersion,
int rotationOverride, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
- bool sharedMode, /*out*/sp<hardware::camera2::ICameraDeviceUser>* device) {
+ bool sharedMode,
+ /*out*/sp<hardware::camera2::ICameraDeviceUser>* device) {
+ return connectDeviceImpl(cameraCb, unresolvedCameraId, oomScoreOffset, targetSdkVersion,
+ rotationOverride, clientAttribution, devicePolicy, sharedMode,
+ /*isVendorClient*/false, device);
+}
+
+Status CameraService::connectDeviceVendor(
+ const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
+ const std::string& unresolvedCameraId,
+ int oomScoreOffset, int targetSdkVersion,
+ int rotationOverride, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
+ bool sharedMode,
+ /*out*/sp<hardware::camera2::ICameraDeviceUser>* device) {
+ return connectDeviceImpl(cameraCb, unresolvedCameraId, oomScoreOffset, targetSdkVersion,
+ rotationOverride, clientAttribution, devicePolicy, sharedMode,
+ /*isVendorClient*/true, device);
+}
+
+Status CameraService::connectDeviceImpl(
+ const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
+ const std::string& unresolvedCameraId,
+ int oomScoreOffset, int targetSdkVersion,
+ int rotationOverride, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
+ bool sharedMode, bool isVendorClient,
+ /*out*/sp<hardware::camera2::ICameraDeviceUser>* device) {
ATRACE_CALL();
RunThreadWithRealtimePriority priorityBump;
Status ret = Status::ok();
@@ -2367,7 +2395,7 @@
cameraCb, cameraId, /*api1CameraId*/ -1, resolvedClientAttribution, systemNativeClient,
API_2, /*shimUpdateOnly*/ false, oomScoreOffset, targetSdkVersion, rotationOverride,
/*forceSlowJpegMode*/ false, unresolvedCameraId, isNonSystemNdk, sharedMode,
- /*out*/ client);
+ isVendorClient, /*out*/ client);
if (!ret.isOk()) {
logRejected(cameraId, clientPid, clientPackageName, toStdString(ret.toString8()));
@@ -2447,7 +2475,8 @@
bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
int rotationOverride, bool forceSlowJpegMode,
const std::string& originalCameraId, bool isNonSystemNdk,
- bool sharedMode, /*out*/ sp<CLIENT>& device) {
+ bool sharedMode, bool isVendorClient,
+ /*out*/ sp<CLIENT>& device) {
binder::Status ret = binder::Status::ok();
nsecs_t openTimeNs = systemTime();
@@ -2546,7 +2575,7 @@
systemNativeClient, cameraId, api1CameraId, facing, orientation,
getpid(), deviceVersionAndTransport, effectiveApiLevel,
overrideForPerfClass, rotationOverride, forceSlowJpegMode,
- originalCameraId, sharedMode,
+ originalCameraId, sharedMode, isVendorClient,
/*out*/ &tmp))
.isOk()) {
return ret;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 6f29ff4..c4d2d67 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -280,6 +280,14 @@
std::vector<hardware::CameraStatus>* cameraStatuses, bool isVendor = false,
bool isProcessLocalTest = false);
+ binder::Status connectDeviceVendor(
+ const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
+ const std::string& cameraId, int scoreOffset, int targetSdkVersion,
+ int rotationOverride, const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy, bool sharedMode,
+ /*out*/
+ sp<hardware::camera2::ICameraDeviceUser>* device);
+
// Monitored UIDs availability notification
void notifyMonitoredUids();
void notifyMonitoredUids(const std::unordered_set<uid_t> ¬ifyUidSet);
@@ -996,7 +1004,16 @@
bool shimUpdateOnly, int scoreOffset, int targetSdkVersion,
int rotationOverride, bool forceSlowJpegMode,
const std::string& originalCameraId, bool isNonSystemNdk,
- bool sharedMode, /*out*/ sp<CLIENT>& device);
+ bool sharedMode, bool isVendorClient,
+ /*out*/ sp<CLIENT>& device);
+
+ binder::Status connectDeviceImpl(
+ const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
+ const std::string& cameraId, int scoreOffset, int targetSdkVersion,
+ int rotationOverride, const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy, bool sharedMode, bool isVendorClient,
+ /*out*/
+ sp<hardware::camera2::ICameraDeviceUser>* device);
// Lock guarding camera service state
Mutex mServiceLock;
@@ -1493,6 +1510,7 @@
apiLevel effectiveApiLevel, bool overrideForPerfClass,
int rotationOverride, bool forceSlowJpegMode,
const std::string& originalCameraId, bool sharedMode,
+ bool isVendorClient,
/*out*/ sp<BasicClient>* client);
static std::string toString(std::set<userid_t> intSet);
diff --git a/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp
index 70647b4..950ea05 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp
+++ b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp
@@ -174,11 +174,19 @@
}
binder::Status AidlCameraDeviceCallbacks::onResultReceived(
- const CameraMetadataNative& result,
+ const CameraMetadataInfo &resultInfo,
const UCaptureResultExtras& resultExtras,
const ::std::vector<UPhysicalCaptureResultInfo>& physicalCaptureResultInfos) {
// Wrap CameraMetadata, resultExtras and physicalCaptureResultInfos in on
// sp<RefBase>-able structure and post it.
+ // We modify metadata - since we want to filter out tags based on the vndk
+ // version, and also this communication is an in process function call.
+ // So we don't use FMQ for the shim layer. FMQ is still used for VNDK IPC.
+ if (resultInfo.getTag() != CameraMetadataInfo::metadata) {
+ ALOGE("Vendor callbacks got metadata in fmq ? ");
+ return binder::Status::ok();
+ }
+ const CameraMetadataNative &result = resultInfo.get<CameraMetadataInfo::metadata>();
sp<ResultWrapper> resultWrapper = new ResultWrapper(const_cast<CameraMetadataNative &>(result),
resultExtras, physicalCaptureResultInfos);
sp<AMessage> msg = new AMessage(kWhatResultReceived, mHandler);
diff --git a/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.h b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.h
index 07bf7d8..6504cdc 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.h
+++ b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.h
@@ -46,6 +46,7 @@
using ::android::frameworks::cameraservice::utils::DeathPipe;
using ::android::hardware::camera2::impl::CameraMetadataNative;
+using CameraMetadataInfo = android::hardware::camera2::CameraMetadataInfo;
using CaptureResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
class AidlCameraDeviceCallbacks : public UBnCameraDeviceCallbacks {
@@ -65,7 +66,8 @@
int64_t timestamp) override;
binder::Status onResultReceived(
- const CameraMetadataNative& result, const CaptureResultExtras& resultExtras,
+ const CameraMetadataInfo &resultInfo,
+ const CaptureResultExtras& resultExtras,
const std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) override;
binder::Status onPrepared(int32_t streamId) override;
diff --git a/services/camera/libcameraservice/aidl/AidlCameraService.cpp b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
index a2c431e..46e2280 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraService.cpp
+++ b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
@@ -177,7 +177,7 @@
kDefaultDeviceId);
clientAttribution.packageName = "";
clientAttribution.attributionTag = std::nullopt;
- binder::Status serviceRet = mCameraService->connectDevice(
+ binder::Status serviceRet = mCameraService->connectDeviceVendor(
callbacks,
in_cameraId,
/* scoreOffset= */ 0,
diff --git a/services/camera/libcameraservice/aidl/AidlUtils.cpp b/services/camera/libcameraservice/aidl/AidlUtils.cpp
index 1ec5072..ea7b9c0 100644
--- a/services/camera/libcameraservice/aidl/AidlUtils.cpp
+++ b/services/camera/libcameraservice/aidl/AidlUtils.cpp
@@ -32,6 +32,7 @@
using aimg::AImageReader_getHGBPFromHandle;
using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
+using CameraMetadataInfo = android::hardware::camera2::CameraMetadataInfo;
// Note: existing data in dst will be gone. Caller still owns the memory of src
void cloneToAidl(const camera_metadata_t* src, SCameraMetadata* dst) {
@@ -254,7 +255,8 @@
SPhysicalCaptureResultInfo dst;
dst.physicalCameraId = src.mPhysicalCameraId;
- const camera_metadata_t *rawMetadata = src.mPhysicalCameraMetadata.getAndLock();
+ const camera_metadata_t *rawMetadata =
+ src.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>().getAndLock();
// Try using fmq at first.
size_t metadata_size = get_camera_metadata_size(rawMetadata);
if ((metadata_size > 0) && (fmq->availableToWrite() > 0)) {
@@ -267,7 +269,7 @@
dst.physicalCameraMetadata.set<SCaptureMetadataInfo::metadata>(std::move(metadata));
}
}
- src.mPhysicalCameraMetadata.unlock(rawMetadata);
+ src.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>().unlock(rawMetadata);
return dst;
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 8c30d54..5679720 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -16,6 +16,11 @@
#define LOG_TAG "CameraDeviceClient"
#define ATRACE_TAG ATRACE_TAG_CAMERA
+#ifdef LOG_NNDEBUG
+#define ALOGVV(...) ALOGV(__VA_ARGS__)
+#else
+#define ALOGVV(...) ((void)0)
+#endif
//#define LOG_NDEBUG 0
#include <com_android_internal_camera_flags.h>
@@ -40,6 +45,7 @@
#include "JpegRCompositeStream.h"
// Convenience methods for constructing binder::Status objects for error returns
+constexpr int32_t METADATA_QUEUE_SIZE = 1 << 20;
#define STATUS_ERROR(errorCode, errorString) \
binder::Status::fromServiceSpecificError(errorCode, \
@@ -80,7 +86,7 @@
const AttributionSourceState& clientAttribution, int callingPid, bool systemNativeClient,
const std::string& cameraId, int cameraFacing, int sensorOrientation, int servicePid,
bool overrideForPerfClass, int rotationOverride, const std::string& originalCameraId,
- bool sharedMode)
+ bool sharedMode, bool isVendorClient)
: Camera2ClientBase(cameraService, remoteCallback, cameraServiceProxyWrapper,
attributionAndPermissionUtils, clientAttribution, callingPid,
systemNativeClient, cameraId, /*API1 camera ID*/ -1, cameraFacing,
@@ -90,7 +96,8 @@
mStreamingRequestId(REQUEST_ID_NONE),
mRequestIdCounter(0),
mOverrideForPerfClass(overrideForPerfClass),
- mOriginalCameraId(originalCameraId) {
+ mOriginalCameraId(originalCameraId),
+ mIsVendorClient(isVendorClient) {
ATRACE_CALL();
ALOGI("CameraDeviceClient %s: Opened", cameraId.c_str());
}
@@ -180,6 +187,14 @@
mHighResolutionSensors.insert(physicalId);
}
}
+ int32_t resultMQSize =
+ property_get_int32("ro.vendor.camera.res.fmq.size", /*default*/METADATA_QUEUE_SIZE);
+ res = CreateMetadataQueue(&mResultMetadataQueue, resultMQSize);
+ if (res != OK) {
+ ALOGE("%s: Creating result metadata queue failed: %s(%d)", __FUNCTION__,
+ strerror(-res), res);
+ return res;
+ }
return OK;
}
@@ -1768,6 +1783,34 @@
return binder::Status::ok();
}
+status_t CameraDeviceClient::CreateMetadataQueue(
+ std::unique_ptr<MetadataQueue>* metadata_queue, uint32_t default_size_bytes) {
+ if (metadata_queue == nullptr) {
+ ALOGE("%s: metadata_queue is nullptr", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ int32_t size = default_size_bytes;
+
+ *metadata_queue =
+ std::make_unique<MetadataQueue>(static_cast<size_t>(size),
+ /*configureEventFlagWord*/ false);
+ if (!(*metadata_queue)->isValid()) {
+ ALOGE("%s: Creating metadata queue (size %d) failed.", __FUNCTION__, size);
+ return NO_INIT;
+ }
+
+ return OK;
+}
+
+binder::Status CameraDeviceClient::getCaptureResultMetadataQueue(
+ android::hardware::common::fmq::MQDescriptor<
+ int8_t, android::hardware::common::fmq::SynchronizedReadWrite>* aidl_return) {
+
+ *aidl_return = mResultMetadataQueue->dupeDesc();
+ return binder::Status::ok();
+}
+
binder::Status CameraDeviceClient::getGlobalAudioRestriction(/*out*/ int32_t* outMode) {
ATRACE_CALL();
binder::Status res;
@@ -2190,16 +2233,76 @@
mCameraServiceProxyWrapper->logClose(mCameraIdStr, closeLatencyMs, hasDeviceError);
}
+size_t CameraDeviceClient::writeResultMetadataIntoResultQueue(
+ const CameraMetadata &resultMetadata) {
+ ATRACE_CALL();
+
+ const camera_metadata_t *resultMetadataP = resultMetadata.getAndLock();
+ size_t resultSize = get_camera_metadata_size(resultMetadataP);
+ if (mResultMetadataQueue != nullptr &&
+ mResultMetadataQueue->write(reinterpret_cast<const int8_t*>(resultMetadataP),
+ resultSize)) {
+ resultMetadata.unlock(resultMetadataP);
+ return resultSize;
+ }
+ resultMetadata.unlock(resultMetadataP);
+ ALOGE(" %s couldn't write metadata into result queue ", __FUNCTION__);
+ return 0;
+}
+
/** Device-related methods */
+std::vector<PhysicalCaptureResultInfo> CameraDeviceClient::convertToFMQ(
+ const std::vector<PhysicalCaptureResultInfo> &physicalResults) {
+ std::vector<PhysicalCaptureResultInfo> retVal;
+ ALOGVV("%s E", __FUNCTION__);
+ for (const auto &srcPhysicalResult : physicalResults) {
+ size_t fmqSize = 0;
+ if (!mIsVendorClient && flags::fmq_metadata()) {
+ fmqSize = writeResultMetadataIntoResultQueue(
+ srcPhysicalResult.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>());
+ }
+ ALOGVV("%s physical metadata write size is %d", __FUNCTION__, (int)fmqSize);
+ if (fmqSize != 0) {
+ retVal.emplace_back(srcPhysicalResult.mPhysicalCameraId, fmqSize);
+ } else {
+ // The flag was off / we're serving VNDK shim call or FMQ write failed.
+ retVal.emplace_back(srcPhysicalResult.mPhysicalCameraId,
+ srcPhysicalResult.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>());
+ }
+ }
+ ALOGVV("%s X", __FUNCTION__);
+ return retVal;
+}
+
void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
ATRACE_CALL();
- ALOGV("%s", __FUNCTION__);
+ ALOGVV("%s E", __FUNCTION__);
// Thread-safe. No lock necessary.
sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
if (remoteCb != NULL) {
- remoteCb->onResultReceived(result.mMetadata, result.mResultExtras,
- result.mPhysicalMetadatas);
+ // Write result metadata into metadataQueue
+ size_t fmqMetadataSize = 0;
+ // Vendor clients need to modify metadata and also this call is in process
+ // before going through FMQ to vendor clients. So don't use FMQ here.
+ if (!mIsVendorClient && flags::fmq_metadata()) {
+ fmqMetadataSize = writeResultMetadataIntoResultQueue(result.mMetadata);
+ }
+ hardware::camera2::impl::CameraMetadataNative resultMetadata;
+ CameraMetadataInfo resultInfo;
+ if (fmqMetadataSize == 0) {
+ // The flag was off / we're serving VNDK shim call or FMQ write failed.
+ resultMetadata = result.mMetadata;
+ resultInfo.set<CameraMetadataInfo::metadata>(resultMetadata);
+ } else {
+ resultInfo.set<CameraMetadataInfo::fmqSize>(fmqMetadataSize);
+ }
+
+ std::vector<PhysicalCaptureResultInfo> physicalMetadatas =
+ convertToFMQ(result.mPhysicalMetadatas);
+
+ remoteCb->onResultReceived(resultInfo, result.mResultExtras,
+ physicalMetadatas);
}
// Access to the composite stream map must be synchronized
@@ -2207,6 +2310,7 @@
for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
mCompositeStreamMap.valueAt(i)->onResultAvailable(result);
}
+ ALOGVV("%s X", __FUNCTION__);
}
binder::Status CameraDeviceClient::checkPidStatus(const char* checkLocation) {
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index a8cf451..691fa8d 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -24,6 +24,8 @@
#include <camera/camera2/SubmitInfo.h>
#include <unordered_map>
+#include <fmq/AidlMessageQueueCpp.h>
+
#include "CameraOfflineSessionClient.h"
#include "CameraService.h"
#include "common/FrameProcessorBase.h"
@@ -161,6 +163,11 @@
virtual binder::Status setCameraAudioRestriction(int32_t mode) override;
+ virtual binder::Status getCaptureResultMetadataQueue(
+ android::hardware::common::fmq::MQDescriptor<
+ int8_t, android::hardware::common::fmq::SynchronizedReadWrite>*
+ aidl_return) override;
+
virtual binder::Status getGlobalAudioRestriction(/*out*/int32_t* outMode) override;
virtual binder::Status switchToOffline(
@@ -182,7 +189,8 @@
const AttributionSourceState& clientAttribution, int callingPid,
bool clientPackageOverride, const std::string& cameraId, int cameraFacing,
int sensorOrientation, int servicePid, bool overrideForPerfClass,
- int rotationOverride, const std::string& originalCameraId, bool sharedMode);
+ int rotationOverride, const std::string& originalCameraId, bool sharedMode,
+ bool isVendorClient);
virtual ~CameraDeviceClient();
virtual status_t initialize(sp<CameraProviderManager> manager,
@@ -233,6 +241,10 @@
*/
protected:
/** FilteredListener implementation **/
+
+ size_t writeResultMetadataIntoResultQueue(const CameraMetadata &result);
+ std::vector<PhysicalCaptureResultInfo> convertToFMQ(
+ const std::vector<PhysicalCaptureResultInfo> &physicalResults);
virtual void onResultAvailable(const CaptureResult& result);
virtual void detachDevice();
@@ -244,6 +256,11 @@
const CameraMetadata &getStaticInfo(const std::string &cameraId);
private:
+ using MetadataQueue = AidlMessageQueueCpp<
+ int8_t, android::hardware::common::fmq::SynchronizedReadWrite>;
+ using CameraMetadataInfo = android::hardware::camera2::CameraMetadataInfo;
+ status_t CreateMetadataQueue(
+ std::unique_ptr<MetadataQueue>* metadata_queue, uint32_t default_size);
// StreamSurfaceId encapsulates streamId + surfaceId for a particular surface.
// streamId specifies the index of the stream the surface belongs to, and the
// surfaceId specifies the index of the surface within the stream. (one stream
@@ -322,6 +339,9 @@
int32_t mRequestIdCounter;
+ // Metadata queue to write the result metadata to.
+ std::unique_ptr<MetadataQueue> mResultMetadataQueue;
+
std::vector<std::string> mPhysicalCameraIds;
// The list of output streams whose surfaces are deferred. We have to track them separately
@@ -361,6 +381,8 @@
// This only exists in case of camera ID Remapping.
const std::string mOriginalCameraId;
+
+ bool mIsVendorClient = false;
};
}; // namespace android
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 71fd3ba..1e73d79 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -299,7 +299,10 @@
ALOGV("%s", __FUNCTION__);
if (mRemoteCallback.get() != NULL) {
- mRemoteCallback->onResultReceived(result.mMetadata, result.mResultExtras,
+ using hardware::camera2::CameraMetadataInfo;
+ CameraMetadataInfo resultInfo;
+ resultInfo.set<CameraMetadataInfo::metadata>(result.mMetadata);
+ mRemoteCallback->onResultReceived(resultInfo, result.mResultExtras,
result.mPhysicalMetadatas);
}
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
index 2322def..31dcce2 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
@@ -29,6 +29,8 @@
namespace android {
namespace camera2 {
+using CameraMetadataInfo = android::hardware::camera2::CameraMetadataInfo;
+
FrameProcessorBase::FrameProcessorBase(wp<FrameProducer> device) :
Thread(/*canCallJava*/false),
mDevice(device),
@@ -99,7 +101,7 @@
for (const auto& physicalFrame : mLastPhysicalFrames) {
lastPhysicalFrames.emplace(physicalFrame.mPhysicalCameraId,
- physicalFrame.mPhysicalCameraMetadata);
+ physicalFrame.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>());
}
}
lastFrame.dump(fd, /*verbosity*/2, /*indentation*/6);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index ed11a96..66dcbc3 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -56,6 +56,7 @@
using namespace android::camera3;
using namespace android::camera3::SessionConfigurationUtils;
using namespace android::hardware::camera;
+using CameraMetadataInfo = android::hardware::camera2::CameraMetadataInfo;
namespace flags = com::android::internal::camera::flags;
namespace android {
@@ -231,11 +232,12 @@
// Update vendor tag id for physical metadata
for (auto& physicalMetadata : result->mPhysicalMetadatas) {
- camera_metadata_t *pmeta = const_cast<camera_metadata_t *>(
- physicalMetadata.mPhysicalCameraMetadata.getAndLock());
+ auto &metadata =
+ physicalMetadata.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>();
+ camera_metadata_t *pmeta = const_cast<camera_metadata_t *>(metadata.getAndLock());
set_camera_metadata_vendor_id(pmeta, states.vendorTagId);
correctMeteringRegions(pmeta);
- physicalMetadata.mPhysicalCameraMetadata.unlock(pmeta);
+ metadata.unlock(pmeta);
}
// Valid result, insert into queue
@@ -362,7 +364,8 @@
for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
camera_metadata_entry timestamp =
- physicalMetadata.mPhysicalCameraMetadata.find(ANDROID_SENSOR_TIMESTAMP);
+ physicalMetadata.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>().
+ find(ANDROID_SENSOR_TIMESTAMP);
if (timestamp.count == 0) {
SET_ERR("No timestamp provided by HAL for physical camera %s frame %d!",
physicalMetadata.mPhysicalCameraId.c_str(), frameNumber);
@@ -415,7 +418,8 @@
return;
}
for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
- res = fixupManualFlashStrengthControlTags(physicalMetadata.mPhysicalCameraMetadata);
+ res = fixupManualFlashStrengthControlTags(physicalMetadata.mCameraMetadataInfo.
+ get<CameraMetadataInfo::metadata>());
if (res != OK) {
SET_ERR("Failed to set flash strength level defaults in physical result"
" metadata: %s (%d)", strerror(-res), res);
@@ -431,7 +435,8 @@
return;
}
for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
- res = fixupAutoframingTags(physicalMetadata.mPhysicalCameraMetadata);
+ res = fixupAutoframingTags(physicalMetadata.mCameraMetadataInfo.
+ get<CameraMetadataInfo::metadata>());
if (res != OK) {
SET_ERR("Failed to set autoframing defaults in physical result metadata: %s (%d)",
strerror(-res), res);
@@ -444,7 +449,7 @@
auto mapper = states.distortionMappers.find(cameraId);
if (mapper != states.distortionMappers.end()) {
res = mapper->second.correctCaptureResult(
- &physicalMetadata.mPhysicalCameraMetadata);
+ &physicalMetadata.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>());
if (res != OK) {
SET_ERR("Unable to correct physical capture result metadata for frame %d: %s (%d)",
frameNumber, strerror(-res), res);
@@ -455,7 +460,8 @@
// Note: Physical camera continues to use SCALER_CROP_REGION to reflect
// zoom levels.
res = states.zoomRatioMappers[cameraId].updateCaptureResult(
- &physicalMetadata.mPhysicalCameraMetadata, /*zoomMethodIsRatio*/false,
+ &physicalMetadata.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>(),
+ /*zoomMethodIsRatio*/false,
/*zoomRatioIs1*/false);
if (res != OK) {
SET_ERR("Failed to update camera %s's physical zoom ratio metadata for "
@@ -474,7 +480,7 @@
const std::string &cameraId = physicalMetadata.mPhysicalCameraId;
res = fixupMonochromeTags(states,
states.physicalDeviceInfoMap.at(cameraId),
- physicalMetadata.mPhysicalCameraMetadata);
+ physicalMetadata.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>());
if (res != OK) {
SET_ERR("Failed to override result metadata: %s (%d)", strerror(-res), res);
return;
@@ -484,7 +490,7 @@
std::unordered_map<std::string, CameraMetadata> monitoredPhysicalMetadata;
for (auto& m : physicalMetadatas) {
monitoredPhysicalMetadata.emplace(m.mPhysicalCameraId,
- CameraMetadata(m.mPhysicalCameraMetadata));
+ CameraMetadata(m.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>()));
}
states.tagMonitor.monitorMetadata(TagMonitor::RESULT,
frameNumber, sensorTimestamp, captureResult.mMetadata,
diff --git a/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.cpp b/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.cpp
index de51ffa..24d9a7e 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.cpp
+++ b/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.cpp
@@ -167,11 +167,19 @@
}
binder::Status H2BCameraDeviceCallbacks::onResultReceived(
- const CameraMetadataNative& result,
+ const CameraMetadataInfo &resultInfo,
const CaptureResultExtras& resultExtras,
const ::std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) {
// Wrap CameraMetadata, resultExtras and physicalCaptureResultInfos in on
// sp<RefBase>-able structure and post it.
+ // We modify metadata - since we want to filter out tags based on the vndk
+ // version, and also this communication is an in process function call.
+ // So we don't use FMQ for the shim layer. FMQ is still used for VNDK IPC.
+ if (resultInfo.getTag() != CameraMetadataInfo::metadata) {
+ ALOGE("Vendor callbacks got metadata in fmq ? ");
+ return binder::Status::ok();
+ }
+ const CameraMetadataNative &result = resultInfo.get<CameraMetadataInfo::metadata>();
sp<ResultWrapper> resultWrapper = new ResultWrapper(const_cast<CameraMetadataNative &>(result),
resultExtras, physicalCaptureResultInfos);
sp<AMessage> msg = new AMessage(kWhatResultReceived, mHandler);
diff --git a/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.h b/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.h
index 98a0dbb..e36c2ea 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraDeviceCallbacks.h
@@ -54,6 +54,7 @@
using hardware::kSynchronizedReadWrite;
using hardware::MessageQueue;
using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using CameraMetadataInfo = android::hardware::camera2::CameraMetadataInfo;
struct H2BCameraDeviceCallbacks :
public H2BConverter<HCameraDeviceCallback, ICameraDeviceCallbacks, BnCameraDeviceCallbacks> {
@@ -72,7 +73,8 @@
int64_t timestamp) override;
virtual binder::Status onResultReceived(
- const CameraMetadataNative& result, const CaptureResultExtras& resultExtras,
+ const CameraMetadataInfo &,
+ const CaptureResultExtras& resultExtras,
const std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) override;
virtual binder::Status onPrepared(int32_t streamId) override;
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 9d140f2..9e66236 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -132,7 +132,7 @@
kDefaultDeviceId);
clientAttribution.packageName = "";
clientAttribution.attributionTag = std::nullopt;
- binder::Status serviceRet = mAidlICameraService->connectDevice(
+ binder::Status serviceRet = mAidlICameraService->connectDeviceVendor(
callbacks, cameraId, 0/*oomScoreOffset*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, ROTATION_OVERRIDE_NONE,
clientAttribution, /*devicePolicy*/0, /*sharedMode*/false, /*out*/&deviceRemote);
diff --git a/services/camera/libcameraservice/hidl/Utils.cpp b/services/camera/libcameraservice/hidl/Utils.cpp
index d0302d0..d37287b 100644
--- a/services/camera/libcameraservice/hidl/Utils.cpp
+++ b/services/camera/libcameraservice/hidl/Utils.cpp
@@ -28,6 +28,7 @@
using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
using aimg::AImageReader_getHGBPFromHandle;
+using CameraMetadataInfo = android::hardware::camera2::CameraMetadataInfo;
// Note: existing data in dst will be gone. Caller still owns the memory of src
void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst) {
@@ -274,7 +275,8 @@
hPhysicalCaptureResultInfo.physicalCameraId =
toString8(physicalCaptureResultInfo.mPhysicalCameraId);
const camera_metadata_t *rawMetadata =
- physicalCaptureResultInfo.mPhysicalCameraMetadata.getAndLock();
+ physicalCaptureResultInfo.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>().
+ getAndLock();
// Try using fmq at first.
size_t metadata_size = get_camera_metadata_size(rawMetadata);
if ((metadata_size > 0) && (captureResultMetadataQueue->availableToWrite() > 0)) {
@@ -287,7 +289,8 @@
hPhysicalCaptureResultInfo.physicalCameraMetadata.metadata(std::move(metadata));
}
}
- physicalCaptureResultInfo.mPhysicalCameraMetadata.unlock(rawMetadata);
+ physicalCaptureResultInfo.mCameraMetadataInfo.get<CameraMetadataInfo::metadata>().
+ unlock(rawMetadata);
return hPhysicalCaptureResultInfo;
}
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
index 6c98837..8c7d39e 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
@@ -54,6 +54,7 @@
using ICameraService::ROTATION_OVERRIDE_NONE;
using ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT;
+using android::hardware::camera2::CameraMetadataInfo;
const int32_t kPreviewThreshold = 8;
const int32_t kNumRequestsTested = 8;
@@ -778,7 +779,7 @@
return binder::Status::ok();
}
- virtual binder::Status onResultReceived(const CameraMetadata& /*metadata*/,
+ virtual binder::Status onResultReceived(const CameraMetadataInfo& /*metadata*/,
const CaptureResultExtras& /*resultExtras*/,
const std::vector<PhysicalCaptureResultInfo>& /*physicalResultInfos*/) {
return binder::Status::ok();
diff --git a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
index ff58c4a..2f035e7 100644
--- a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
@@ -34,6 +34,7 @@
using namespace android;
using namespace android::hardware::camera;
+using android::hardware::camera2::CameraMetadataInfo;
// Empty service listener.
class TestCameraServiceListener : public hardware::BnCameraServiceListener {
@@ -107,7 +108,7 @@
return binder::Status::ok();
}
- virtual binder::Status onResultReceived(const CameraMetadata& /*metadata*/,
+ virtual binder::Status onResultReceived(const CameraMetadataInfo& /*metadata*/,
const CaptureResultExtras& /*resultExtras*/,
const std::vector<PhysicalCaptureResultInfo>& /*physicalResultInfos*/) {
return binder::Status::ok();