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/Android.bp b/services/camera/libcameraservice/Android.bp
index b92c7d1..c912f63 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -53,6 +53,7 @@
"device3/DistortionMapper.cpp",
"gui/RingBufferConsumer.cpp",
"utils/CameraThreadState.cpp",
+ "hidl/AidlCameraServiceListener.cpp",
"hidl/HidlCameraService.cpp",
"hidl/Convert.cpp",
"utils/CameraTraces.cpp",
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
new file mode 100644
index 0000000..110ef8e
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 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 <hidl/AidlCameraServiceListener.h>
+#include <hidl/Convert.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace service {
+namespace V2_0 {
+namespace implementation {
+
+using hardware::cameraservice::utils::conversion::convertToHidlCameraDeviceStatus;
+
+binder::Status H2BCameraServiceListener::onStatusChanged(
+ int32_t status, const ::android::String16& cameraId) {
+ HCameraDeviceStatus hCameraDeviceStatus = convertToHidlCameraDeviceStatus(status);
+ CameraStatusAndId cameraStatusAndId;
+ cameraStatusAndId.deviceStatus = hCameraDeviceStatus;
+ cameraStatusAndId.cameraId = String8(cameraId).string();
+ auto ret = mBase->onStatusChanged(cameraStatusAndId);
+ if (!ret.isOk()) {
+ ALOGE("%s OnStatusChanged callback failed due to %s",__FUNCTION__,
+ ret.description().c_str());
+ }
+ return binder::Status::ok();
+}
+
+::android::binder::Status H2BCameraServiceListener::onTorchStatusChanged(
+ int32_t, const ::android::String16&) {
+ // We don't implement onTorchStatusChanged
+ return binder::Status::ok();
+}
+
+} // implementation
+} // V2_0
+} // common
+} // cameraservice
+} // frameworks
+} // android
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
new file mode 100644
index 0000000..ca9143d
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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 <mutex>
+#include <thread>
+
+#include <android/frameworks/cameraservice/common/2.0/types.h>
+#include <android/frameworks/cameraservice/service/2.0/ICameraServiceListener.h>
+#include <android/frameworks/cameraservice/device/2.0/types.h>
+#include <android/hardware/BnCameraServiceListener.h>
+#include <android/hardware/BpCameraServiceListener.h>
+
+#include <hidl/Status.h>
+#include <hidl/CameraHybridInterface.h>
+
+namespace android {
+namespace frameworks {
+namespace cameraservice {
+namespace service {
+namespace V2_0 {
+namespace implementation {
+
+using hardware::BnCameraServiceListener;
+using hardware::BpCameraServiceListener;
+using camerahybrid::H2BConverter;
+using HCameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
+typedef frameworks::cameraservice::service::V2_0::ICameraServiceListener HCameraServiceListener;
+
+struct H2BCameraServiceListener :
+ public H2BConverter<HCameraServiceListener, ICameraServiceListener, BnCameraServiceListener> {
+ H2BCameraServiceListener(const sp<HalInterface>& base) : CBase(base) { }
+
+ ~H2BCameraServiceListener() { }
+
+ virtual ::android::binder::Status onStatusChanged(int32_t status,
+ const ::android::String16& cameraId) override;
+
+ virtual ::android::binder::Status onTorchStatusChanged(
+ int32_t status, const ::android::String16& cameraId) override;
+};
+
+} // implementation
+} // V2_0
+} // service
+} // cameraservice
+} // frameworks
+} // android
diff --git a/services/camera/libcameraservice/hidl/CameraHybridInterface.h b/services/camera/libcameraservice/hidl/CameraHybridInterface.h
new file mode 100644
index 0000000..baf0112
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/CameraHybridInterface.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2018 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_CAMERA_HYBRIDINTERFACE_H
+#define ANDROID_CAMERA_HYBRIDINTERFACE_H
+
+#include <vector>
+#include <mutex>
+
+#include <binder/Parcel.h>
+#include <hidl/HidlSupport.h>
+
+namespace android {
+namespace camerahybrid {
+typedef ::android::hidl::base::V1_0::IBase HInterface;
+
+template <
+ typename HINTERFACE,
+ typename INTERFACE,
+ typename BNINTERFACE >
+class H2BConverter : public BNINTERFACE {
+public:
+ typedef H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE> CBase; // Converter Base
+ typedef INTERFACE BaseInterface;
+ typedef HINTERFACE HalInterface;
+
+ H2BConverter(const sp<HalInterface>& base) : mBase(base) {}
+ virtual sp<HalInterface> getHalInterface() { return mBase; }
+ virtual status_t linkToDeath(
+ const sp<IBinder::DeathRecipient>& recipient,
+ void* cookie = nullptr,
+ uint32_t flags = 0);
+ virtual status_t unlinkToDeath(
+ const wp<IBinder::DeathRecipient>& recipient,
+ void* cookie = nullptr,
+ uint32_t flags = 0,
+ wp<IBinder::DeathRecipient>* outRecipient = nullptr);
+
+protected:
+ sp<HalInterface> mBase;
+ struct Obituary : public hardware::hidl_death_recipient {
+ wp<IBinder::DeathRecipient> recipient;
+ void* cookie;
+ uint32_t flags;
+ wp<IBinder> who;
+ Obituary(
+ const wp<IBinder::DeathRecipient>& r,
+ void* c, uint32_t f,
+ const wp<IBinder>& w) :
+ recipient(r), cookie(c), flags(f), who(w) {
+ }
+ Obituary(const Obituary& o) :
+ recipient(o.recipient),
+ cookie(o.cookie),
+ flags(o.flags),
+ who(o.who) {
+ }
+ Obituary& operator=(const Obituary& o) {
+ recipient = o.recipient;
+ cookie = o.cookie;
+ flags = o.flags;
+ who = o.who;
+ return *this;
+ }
+ void serviceDied(uint64_t, const wp<HInterface>&) override {
+ sp<IBinder::DeathRecipient> dr = recipient.promote();
+ if (dr != nullptr) {
+ dr->binderDied(who);
+ }
+ }
+ };
+ std::mutex mObituariesLock;
+ std::vector<sp<Obituary> > mObituaries;
+};
+
+template <
+ typename HINTERFACE,
+ typename INTERFACE,
+ typename BNINTERFACE>
+status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>::
+ linkToDeath(
+ const sp<IBinder::DeathRecipient>& recipient,
+ void* cookie, uint32_t flags) {
+ LOG_ALWAYS_FATAL_IF(recipient == nullptr,
+ "linkToDeath(): recipient must be non-nullptr");
+ {
+ std::lock_guard<std::mutex> lock(mObituariesLock);
+ mObituaries.push_back(new Obituary(recipient, cookie, flags, this));
+ if (!mBase->linkToDeath(mObituaries.back(), 0)) {
+ return DEAD_OBJECT;
+ }
+ }
+ return NO_ERROR;
+}
+
+template <
+ typename HINTERFACE,
+ typename INTERFACE,
+ typename BNINTERFACE>
+status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>::
+ unlinkToDeath(
+ const wp<IBinder::DeathRecipient>& recipient,
+ void* cookie, uint32_t flags,
+ wp<IBinder::DeathRecipient>* outRecipient) {
+ std::lock_guard<std::mutex> lock(mObituariesLock);
+ for (auto i = mObituaries.begin(); i != mObituaries.end(); ++i) {
+ if ((flags = (*i)->flags) && (
+ (recipient == (*i)->recipient) ||
+ ((recipient == nullptr) && (cookie == (*i)->cookie)))) {
+ if (outRecipient != nullptr) {
+ *outRecipient = (*i)->recipient;
+ }
+ bool success = mBase->unlinkToDeath(*i);
+ mObituaries.erase(i);
+ return success ? NO_ERROR : DEAD_OBJECT;
+ }
+ }
+ return NAME_NOT_FOUND;
+}
+
+} // namespace camerahybrid
+} // namespace android
+
+#endif // ANDROID_CAMERA_HYBRIDINTERFACE_H
+
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;
}
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.h b/services/camera/libcameraservice/hidl/HidlCameraService.h
index e9daf28..eead0bc 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.h
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.h
@@ -73,7 +73,19 @@
private:
HidlCameraService(android::CameraService *cs) : mAidlICameraService(cs) { };
- android::CameraService * const mAidlICameraService = nullptr;
+ sp<hardware::ICameraServiceListener> searchListenerCacheLocked(
+ sp<HCameraServiceListener> listener, /*removeIfFound*/ bool shouldRemove = false);
+
+ void addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
+ sp<hardware::ICameraServiceListener> csListener);
+
+ android::CameraService *const mAidlICameraService = nullptr;
+
+ Mutex mListenerListLock;
+
+ using HIListeners =
+ std::pair<sp<HCameraServiceListener>, sp<ICameraServiceListener>>;
+ std::list<HIListeners> mListeners;
};
} // namespace implementation