diff options
author | 2021-06-10 19:38:18 +0000 | |
---|---|---|
committer | 2021-06-10 19:38:18 +0000 | |
commit | 936fc19aa0ca565dc0903c577658676ad76575b7 (patch) | |
tree | 5ae9c7539061131561288ed094d17ec86310aa64 /libs/binder/RpcState.cpp | |
parent | e27baffb9afc9399aab7116fe795d3d35df7b19e (diff) | |
parent | 195edb85d1fddd888a1ea23ea48c61e0b384be15 (diff) |
Merge changes Id38049ed,I13bc9126,I9fbc7594
* changes:
libbinder: handle ExclusiveSocket failure
libbinder: RPC know when connections setup
libbinder: RPC process oneway w/ 'tail call'
Diffstat (limited to 'libs/binder/RpcState.cpp')
-rw-r--r-- | libs/binder/RpcState.cpp | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp index 6899981e83..53eba5aea6 100644 --- a/libs/binder/RpcState.cpp +++ b/libs/binder/RpcState.cpp @@ -265,6 +265,27 @@ status_t RpcState::rpcRec(const base::unique_fd& fd, const sp<RpcSession>& sessi return OK; } +status_t RpcState::sendConnectionInit(const base::unique_fd& fd, const sp<RpcSession>& session) { + RpcClientConnectionInit init{ + .msg = RPC_CONNECTION_INIT_OKAY, + }; + return rpcSend(fd, session, "connection init", &init, sizeof(init)); +} + +status_t RpcState::readConnectionInit(const base::unique_fd& fd, const sp<RpcSession>& session) { + RpcClientConnectionInit init; + if (status_t status = rpcRec(fd, session, "connection init", &init, sizeof(init)); status != OK) + return status; + + static_assert(sizeof(init.msg) == sizeof(RPC_CONNECTION_INIT_OKAY)); + if (0 != strncmp(init.msg, RPC_CONNECTION_INIT_OKAY, sizeof(init.msg))) { + ALOGE("Connection init message unrecognized %.*s", static_cast<int>(sizeof(init.msg)), + init.msg); + return BAD_VALUE; + } + return OK; +} + sp<IBinder> RpcState::getRootObject(const base::unique_fd& fd, const sp<RpcSession>& session) { Parcel data; data.markForRpc(session); @@ -565,7 +586,7 @@ status_t RpcState::processTransact(const base::unique_fd& fd, const sp<RpcSessio status != OK) return status; - return processTransactInternal(fd, session, std::move(transactionData), nullptr /*targetRef*/); + return processTransactInternal(fd, session, std::move(transactionData)); } static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t dataSize, @@ -578,7 +599,13 @@ static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t d } status_t RpcState::processTransactInternal(const base::unique_fd& fd, const sp<RpcSession>& session, - CommandData transactionData, sp<IBinder>&& targetRef) { + CommandData transactionData) { + // for 'recursive' calls to this, we have already read and processed the + // binder from the transaction data and taken reference counts into account, + // so it is cached here. + sp<IBinder> targetRef; +processTransactInternalTailCall: + if (transactionData.size() < sizeof(RpcWireTransaction)) { ALOGE("Expecting %zu but got %zu bytes for RpcWireTransaction. Terminating!", sizeof(RpcWireTransaction), transactionData.size()); @@ -751,13 +778,12 @@ status_t RpcState::processTransactInternal(const base::unique_fd& fd, const sp<R // - gotta go fast auto& todo = const_cast<BinderNode::AsyncTodo&>(it->second.asyncTodo.top()); - CommandData nextData = std::move(todo.data); - sp<IBinder> nextRef = std::move(todo.ref); + // reset up arguments + transactionData = std::move(todo.data); + targetRef = std::move(todo.ref); it->second.asyncTodo.pop(); - _l.unlock(); - return processTransactInternal(fd, session, std::move(nextData), - std::move(nextRef)); + goto processTransactInternalTailCall; } } return OK; |