aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/kdbinder/binder/ProcessState.h17
-rw-r--r--libs/kdbinder/binder/Parcel.cpp12
-rw-r--r--libs/kdbinder/binder/ProcessState.cpp50
3 files changed, 73 insertions, 6 deletions
diff --git a/include/kdbinder/binder/ProcessState.h b/include/kdbinder/binder/ProcessState.h
index 0e5893d..97c831b 100644
--- a/include/kdbinder/binder/ProcessState.h
+++ b/include/kdbinder/binder/ProcessState.h
@@ -46,6 +46,7 @@ class ProcessState : public virtual RefBase {
friend class IPCThreadState;
// BpServiceManager needs to call registerService.
friend class BpServiceManager;
+ friend class Parcel;
ProcessState();
~ProcessState() = default;
@@ -59,6 +60,22 @@ class ProcessState : public virtual RefBase {
// Add the given Binder object in mServiceTable.
int32_t registerService(sp<IBinder> binder, String16 name);
+ int32_t registerBinder(sp<IBinder> binder);
+
+ // Get the handle of a given Binder.
+ // - If the Binder is local:
+ // Search it in mServiceTable and return the handle. If it
+ // does not find it, it will add it to the table and return the new
+ // handle.
+ // - If the Binder is remote:
+ // Simply lookup its handle and return it.
+ int32_t getHandleForBinder(sp<IBinder> binder);
+
+ // Get the Binder object with the given handle.
+ // This method will search mServiceTable and return the local Binder
+ // that it found. If it did not find it, then it will create a new
+ // remove Binder.
+ sp<IBinder> getBinderForHandle(int32_t handle);
// Each Binder object managed by ProcessState need a kdbus::Connection
// associated with them.
diff --git a/libs/kdbinder/binder/Parcel.cpp b/libs/kdbinder/binder/Parcel.cpp
index 0e10fd2..a3fad31 100644
--- a/libs/kdbinder/binder/Parcel.cpp
+++ b/libs/kdbinder/binder/Parcel.cpp
@@ -431,8 +431,9 @@ status_t Parcel::writeString16(const char16_t* str, size_t len) {
}
status_t Parcel::writeStrongBinder(const sp<IBinder>& val) {
- // TODO: unimplemented
- return flatten_binder(ProcessState::self(), val, this);
+ int64_t handle = ProcessState::self()->getHandleForBinder(val);
+
+ return writeInt64(handle);
}
status_t Parcel::writeWeakBinder(const wp<IBinder>& val) {
@@ -777,10 +778,9 @@ const char16_t* Parcel::readString16Inplace(size_t* outLen) const {
}
sp<IBinder> Parcel::readStrongBinder() const {
- sp<IBinder> val;
- // TODO: unimplemented
- unflatten_binder(ProcessState::self(), *this, &val);
- return val;
+ int64_t handle = readInt64();
+
+ return ProcessState::self()->getBinderForHandle(handle);
}
wp<IBinder> Parcel::readWeakBinder() const {
diff --git a/libs/kdbinder/binder/ProcessState.cpp b/libs/kdbinder/binder/ProcessState.cpp
index 5235510..8ea144d 100644
--- a/libs/kdbinder/binder/ProcessState.cpp
+++ b/libs/kdbinder/binder/ProcessState.cpp
@@ -99,4 +99,54 @@ int32_t ProcessState::registerService(sp<IBinder> binder, String16 name) {
return handle;
}
+int32_t ProcessState::registerBinder(sp<IBinder> binder) {
+ auto connection_for_binder = kdbus::Connection::hello(
+ "0-services",
+ "BBinder");
+
+ int32_t handle = connection_for_binder->id;
+
+ {
+ // add binder to table.
+ AutoMutex _l(mServiceLock);
+ mServiceTable.emplace_back(std::move(connection_for_binder), binder);
+ }
+
+ return handle;
+}
+
+int32_t ProcessState::getHandleForBinder(sp<IBinder> binder) {
+ IBinder *local = binder->localBinder();
+
+ if (local) {
+ auto it = std::find_if(mServiceTable.cbegin(),
+ mServiceTable.cend(),
+ [&binder](const struct binder_entry& entry) {
+ return entry.binder == binder;
+ });
+ if (it == mServiceTable.cend()) {
+ return registerBinder(binder);
+ } else {
+ return it->connection->id;
+ }
+ } else {
+ BpBinder *remote = binder->remoteBinder();
+
+ return remote->handle();
+ }
+}
+
+sp<IBinder> ProcessState::getBinderForHandle(int32_t handle) {
+ auto it = std::find_if(mServiceTable.cbegin(),
+ mServiceTable.cend(),
+ [&handle](const struct binder_entry& entry) {
+ return entry.connection->id == (uint64_t) handle;
+ });
+ if (it != mServiceTable.cend()) {
+ return it->binder;
+ } else {
+ return new BpBinder(handle);
+ }
+}
+
} // namespace android