diff options
-rw-r--r-- | include/kdbinder/binder/ProcessState.h | 17 | ||||
-rw-r--r-- | libs/kdbinder/binder/Parcel.cpp | 12 | ||||
-rw-r--r-- | libs/kdbinder/binder/ProcessState.cpp | 50 |
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 |