summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward Chen <howardsoc@google.com>2017-10-13 14:21:46 +0800
committerSteven Moreland <smoreland@google.com>2017-10-19 01:12:38 -0700
commit9bc35c40a958afcc5711c5c4b306ddc7b68974b0 (patch)
tree7e14ea2a56b768d581fb47062b6a191f2c618cf8
parent77f4c859c984264a232a6fa2617c0279be25a366 (diff)
downloadlibhidl-9bc35c40a958afcc5711c5c4b306ddc7b68974b0.tar.gz
Add HidlMemory
HidlMemory is a wrapper class to support sp<> for hidl_memory. It also provides a factory method to create an instance of the 'ashmem' hidl_memory from a opened file descriptor. The number of factory methods can be increase to support other type of hidl_memory without break the ABI. Change-Id: I18176aecdde1c5c1e10582a4a2e87fe466730e17 Bug: 67758915 Test: with the master branch on the Pixel phone.
-rw-r--r--base/HidlSupport.cpp27
-rw-r--r--base/include/hidl/HidlSupport.h27
2 files changed, 54 insertions, 0 deletions
diff --git a/base/HidlSupport.cpp b/base/HidlSupport.cpp
index 4de7f7c..f857281 100644
--- a/base/HidlSupport.cpp
+++ b/base/HidlSupport.cpp
@@ -273,6 +273,33 @@ bool hidl_string::empty() const {
return mSize == 0;
}
+sp<HidlMemory> HidlMemory::getInstance(hidl_memory&& mem) {
+ sp<HidlMemory> instance = new HidlMemory();
+ *instance = std::move(mem);
+ return instance;
+}
+
+sp<HidlMemory> HidlMemory::getInstance(const hidl_string& name, int fd, uint64_t size) {
+ native_handle_t* handle = native_handle_create(1, 0);
+ if (!handle) {
+ close(fd);
+ LOG(ERROR) << "native_handle_create fails";
+ return new HidlMemory();
+ }
+ handle->data[0] = fd;
+
+ hidl_handle hidlHandle;
+ hidlHandle.setTo(handle, true /* shouldOwn */);
+
+ sp<HidlMemory> instance = new HidlMemory(name, std::move(hidlHandle), size);
+ return instance;
+}
+
+// it's required to have at least one out-of-line method to avoid weak vtable
+HidlMemory::~HidlMemory() {
+ hidl_memory::~hidl_memory();
+}
+
} // namespace hardware
} // namespace android
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index ab16709..78e0867 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -268,6 +268,9 @@ struct hidl_memory {
return mSize;
}
+ // @return true if it's valid
+ inline bool valid() const { return handle() != nullptr; }
+
// offsetof(hidl_memory, mHandle) exposed since mHandle is private.
static const size_t kOffsetOfHandle;
// offsetof(hidl_memory, mName) exposed since mHandle is private.
@@ -279,6 +282,30 @@ private:
hidl_string mName __attribute__ ((aligned(8)));
};
+// HidlMemory is a wrapper class to support sp<> for hidl_memory. It also
+// provides factory methods to create an instance from hidl_memory or
+// from a opened file descriptor. The number of factory methods can be increase
+// to support other type of hidl_memory without break the ABI.
+class HidlMemory : public virtual hidl_memory, public virtual ::android::RefBase {
+public:
+ static sp<HidlMemory> getInstance(hidl_memory&& mem);
+
+ static sp<HidlMemory> getInstance(const hidl_string& name, hidl_handle&& handle, uint64_t size);
+ // @param fd, shall be opened and points to the resource.
+ // @note this method takes the ownership of the fd and will close it in
+ // destructor
+ static sp<HidlMemory> getInstance(const hidl_string& name, int fd, uint64_t size);
+
+protected:
+ HidlMemory() : hidl_memory() {}
+ HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size)
+ : hidl_memory(name, std::move(handle), size) {}
+ ~HidlMemory();
+ HidlMemory& operator=(hidl_memory&& src) {
+ hidl_memory::operator=(src);
+ return *this;
+ }
+};
////////////////////////////////////////////////////////////////////////////////
template<typename T>