cameraserver: Implement AIDL wrapper class for HIDL ICameraServiceListener.
Bug: 110364143
Test: (build) mm -j64
Change-Id: Ibf1da18d0fac5ddaab5da8df52c4183b3aaadbfc
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 981f431..f34f903 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -17,6 +17,7 @@
#include <hidl/Convert.h>
#include <hidl/HidlCameraService.h>
+#include <hidl/AidlCameraServiceListener.h>
#include <hidl/HidlTransportSupport.h>
@@ -33,6 +34,7 @@
using hardware::cameraservice::utils::conversion::B2HStatus;
using hardware::Void;
+using service::V2_0::implementation::H2BCameraServiceListener;
using HCameraMetadataType = android::frameworks::cameraservice::common::V2_0::CameraMetadataType;
using HVendorTag = android::frameworks::cameraservice::common::V2_0::VendorTag;
using HVendorTagSection = android::frameworks::cameraservice::common::V2_0::VendorTagSection;
@@ -85,12 +87,74 @@
return Void();
}
+void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
+ sp<hardware::ICameraServiceListener> csListener) {
+ mListeners.emplace_back(std::make_pair(hListener, csListener));
+}
+
+sp<hardware::ICameraServiceListener>
+HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
+ bool shouldRemove) {
+ // Go through the mListeners list and compare the listener with the HIDL
+ // listener registered.
+ auto it = mListeners.begin();
+ sp<ICameraServiceListener> csListener = nullptr;
+ for (;it != mListeners.end(); it++) {
+ if (hardware::interfacesEqual(it->first, hListener)) {
+ break;
+ }
+ }
+ if (it != mListeners.end()) {
+ csListener = it->second;
+ if (shouldRemove) {
+ mListeners.erase(it);
+ }
+ }
+ return csListener;
+}
+
Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
addListener_cb _hidl_cb) {
- // To silence Wunused-parameter.
- (void)hCsListener;
- (void)_hidl_cb;
-
+ if (mAidlICameraService == nullptr) {
+ _hidl_cb(HStatus::UNKNOWN_ERROR, {});
+ return Void();
+ }
+ if (hCsListener == nullptr) {
+ ALOGE("%s listener must not be NULL", __FUNCTION__);
+ _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
+ return Void();
+ }
+ sp<hardware::ICameraServiceListener> csListener = nullptr;
+ // Check the cache for previously registered callbacks
+ {
+ Mutex::Autolock l(mListenerListLock);
+ csListener = searchListenerCacheLocked(hCsListener);
+ if (csListener == nullptr) {
+ // Wrap an hCsListener with AidlCameraServiceListener and pass it to
+ // CameraService.
+ csListener = new H2BCameraServiceListener(hCsListener);
+ // Add to cache
+ addToListenerCacheLocked(hCsListener, csListener);
+ } else {
+ ALOGE("%s: Trying to add a listener %p already registered",
+ __FUNCTION__, hCsListener.get());
+ _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
+ return Void();
+ }
+ }
+ std::vector<hardware::CameraStatus> cameraStatusAndIds{};
+ binder::Status serviceRet = mAidlICameraService->addListener(csListener, &cameraStatusAndIds);
+ HStatus status = HStatus::NO_ERROR;
+ if (!serviceRet.isOk()) {
+ ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
+ status = B2HStatus(serviceRet);
+ _hidl_cb(status, {});
+ return Void();
+ }
+ hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
+ //Convert cameraStatusAndIds to HIDL and call callback
+ convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
+ _hidl_cb(status, hCameraStatusAndIds);
return Void();
}
@@ -99,6 +163,17 @@
ALOGE("%s listener must not be NULL", __FUNCTION__);
return HStatus::ILLEGAL_ARGUMENT;
}
+ sp<ICameraServiceListener> csListener = nullptr;
+ {
+ Mutex::Autolock l(mListenerListLock);
+ csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
+ }
+ if (csListener != nullptr) {
+ mAidlICameraService->removeListener(csListener);
+ } else {
+ ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
+ return HStatus::ILLEGAL_ARGUMENT;
+ }
return HStatus::NO_ERROR;
}