Callback elision for HIDL interfaces.
Test: mma, hidl_test
Bug: 31380743
Change-Id: If5f0dc0279e717dafaf416776be89cc854c6f856
diff --git a/base/include/hidl/Status.h b/base/include/hidl/Status.h
index c0edb84..f17c968 100644
--- a/base/include/hidl/Status.h
+++ b/base/include/hidl/Status.h
@@ -23,6 +23,7 @@
#include <android-base/macros.h>
#include <hidl/HidlInternal.h>
#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
namespace android {
namespace hardware {
@@ -146,6 +147,13 @@
private:
Status mStatus {};
mutable bool mCheckedStatus = false;
+ protected:
+ void checkStatus() const {
+ if (!isOk()) {
+ logAlwaysFatal("Attempted to retrieve value from hidl service, "
+ "but there was a transport error.");
+ }
+ }
public:
return_status() {}
return_status(Status s) : mStatus(s) {}
@@ -190,15 +198,33 @@
~Return() = default;
operator T() const {
- if (!isOk()) {
- logAlwaysFatal("Attempted to retrieve value from hidl service, "
- "but there was a transport error.");
- }
+ checkStatus();
return mVal;
}
};
+template<typename T> class Return<sp<T>> : public details::return_status {
+private:
+ sp<T> mVal {};
+public:
+ Return(sp<T> v) : details::return_status(), mVal{v} {}
+ Return(T* v) : details::return_status(), mVal{v} {}
+ // Constructors matching a different type (that is related by inheritance)
+ template<typename U> Return(sp<U> v) : details::return_status(), mVal{v} {}
+ template<typename U> Return(U* v) : details::return_status(), mVal{v} {}
+ Return(Status s) : details::return_status(s) {}
+
+ Return(const Return &) = default;
+ ~Return() = default;
+
+ operator sp<T>() const {
+ checkStatus();
+ return mVal;
+ }
+};
+
+
template<> class Return<void> : public details::return_status {
public:
Return() : details::return_status() {}
diff --git a/libhidlmemory/mapping.cpp b/libhidlmemory/mapping.cpp
index b4fa123..3761f99 100644
--- a/libhidlmemory/mapping.cpp
+++ b/libhidlmemory/mapping.cpp
@@ -40,19 +40,14 @@
LOG(FATAL) << "IMapper must be a passthrough service.";
}
- sp<IMemory> retMemory = nullptr;
-
- Return<void> ret = mapper->mapMemory(memory,
- [&retMemory](const auto &mapped) {
- retMemory = mapped;
- });
+ Return<sp<IMemory>> ret = mapper->mapMemory(memory);
if (!ret.isOk()) {
LOG(FATAL) << "hidl_memory map returned transport error.";
}
- return retMemory;
+ return ret;
}
} // namespace hardware
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/transport/memory/1.0/default/AshmemMapper.cpp b/transport/memory/1.0/default/AshmemMapper.cpp
index 37eb8af..bef4767 100644
--- a/transport/memory/1.0/default/AshmemMapper.cpp
+++ b/transport/memory/1.0/default/AshmemMapper.cpp
@@ -27,10 +27,9 @@
namespace implementation {
// Methods from ::android::hidl::memory::V1_0::IMapper follow.
-Return<void> AshmemMapper::mapMemory(const hidl_memory& mem, mapMemory_cb _hidl_cb) {
+Return<sp<IMemory>> AshmemMapper::mapMemory(const hidl_memory& mem) {
if (mem.handle()->numFds == 0) {
- _hidl_cb(nullptr);
- return Void();
+ return nullptr;
}
int fd = mem.handle()->data[0];
@@ -38,14 +37,10 @@
if (data == MAP_FAILED) {
// mmap never maps at address zero without MAP_FIXED, so we can avoid
// exposing clients to MAP_FAILED.
- _hidl_cb(nullptr);
- return Void();
+ return nullptr;
}
- sp<IMemory> memory = new AshmemMemory(mem, data);
-
- _hidl_cb(memory);
- return Void();
+ return new AshmemMemory(mem, data);
}
} // namespace implementation
diff --git a/transport/memory/1.0/default/AshmemMapper.h b/transport/memory/1.0/default/AshmemMapper.h
index c6cfc37..3d3a7e1 100644
--- a/transport/memory/1.0/default/AshmemMapper.h
+++ b/transport/memory/1.0/default/AshmemMapper.h
@@ -28,6 +28,7 @@
namespace implementation {
using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hidl::memory::V1_0::IMemory;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
@@ -38,7 +39,7 @@
struct AshmemMapper : public IMapper {
// Methods from ::android::hidl::memory::V1_0::IMapper follow.
- Return<void> mapMemory(const hidl_memory& mem, mapMemory_cb _hidl_cb) override;
+ Return<sp<IMemory>> mapMemory(const hidl_memory& mem) override;
};