Loading libs/binder/trusty/README.md +39 −33 Original line number Original line Diff line number Diff line # Binder for Trusty # Binder for Trusty This is the Trusty port of the libbinder library. This is the Trusty port of the libbinder library. To build it, take the following steps: To build it, first you will need a checkout of the Trusty tree: * Check out copies of the Trusty and AOSP repositories. * Apply the patches from the `trusty_binder` topic on both repositories. * Build Trusty normally using `build.py`. * Run the sample AIDL test for Trusty: ```shell ```shell $ ./build-root/.../run --headless --boot-test com.android.trusty.aidl.test $ mkdir /path/to/trusty $ cd /path/to/trusty $ repo init -u https://android.googlesource.com/trusty/manifest -b master $ repo sync -j$(nproc) -c --no-tags ``` ``` To run the Android-Trusty IPC test, do the following: After the checkout is complete, you can use the `build.py` script for both building and testing Trusty. For a quick build without any tests, run: * Build AOSP for the `qemu_trusty_arm64-userdebug` target: ```shell ```shell $ lunch qemu_trusty_arm64-userdebug $ ./trusty/vendor/google/aosp/scripts/build.py generic-arm64-test-debug $ m ``` ``` * In the Trusty directory, run the emulator with the newly built Android: This will build the smaller `generic-arm64-test-debug` project which does not run any tests. The qemu-generic-arm64-test-debug` project includes the QEMU emulator and a full Trusty test suite, including a set of libbinder tests. To run the latter, use the command: ```shell ```shell $ ./build-root/.../run --android /path/to/aosp $ ./trusty/vendor/google/aosp/scripts/build.py \ --test "boot-test:com.android.trusty.binder.test" \ qemu-generic-arm64-test-debug ``` ``` * Using either `adb` or the shell inside the emulator itself, run the Trusty Binder test as root: ## Building AIDL files on Trusty ```shell To compile AIDL interfaces into Trusty libraries, include the `make/aidl.mk` # /data/nativetest64/vendor/trusty_binder_test/trusty_binder_test in your `rules.mk` file, e.g.: ``` ``` LOCAL_DIR := $(GET_LOCAL_DIR) ## Running the AIDL compiler MODULE := $(LOCAL_DIR) For now, you will need to run the AIDL compiler manually to generate the C++ source code for Trusty clients and services. The general syntax is: MODULE_AIDLS := \ ```shell $(LOCAL_DIR)/IFoo.aidl \ $ aidl --lang=cpp -o <output directory> -h <output header directory> <AIDL files...> include make/aidl.mk ``` ``` The compiler will emit some `.cpp` files in the output directory and their ## Examples corresponding `.h` files in the header directory. The Trusty tree contains some sample test apps at `trusty/user/app/sample/binder-test`. libs/binder/trusty/RpcServerTrusty.cpp +28 −7 Original line number Original line Diff line number Diff line Loading @@ -104,8 +104,17 @@ int RpcServerTrusty::handleConnect(const tipc_port* port, handle_t chan, const u return; return; } } /* Save the session for easy access */ /* Save the session and connection for the other callbacks */ *ctx_p = session.get(); auto* channelContext = new (std::nothrow) ChannelContext; if (channelContext == nullptr) { rc = ERR_NO_MEMORY; return; } channelContext->session = std::move(session); channelContext->connection = std::move(result.connection); *ctx_p = channelContext; }; }; base::unique_fd clientFd(chan); base::unique_fd clientFd(chan); Loading @@ -119,9 +128,14 @@ int RpcServerTrusty::handleConnect(const tipc_port* port, handle_t chan, const u } } int RpcServerTrusty::handleMessage(const tipc_port* port, handle_t chan, void* ctx) { int RpcServerTrusty::handleMessage(const tipc_port* port, handle_t chan, void* ctx) { auto* session = reinterpret_cast<RpcSession*>(ctx); auto* channelContext = reinterpret_cast<ChannelContext*>(ctx); status_t status = session->state()->drainCommands(session->mConnections.mIncoming[0], session, LOG_ALWAYS_FATAL_IF(channelContext == nullptr, RpcState::CommandType::ANY); "bad state: message received on uninitialized channel"); auto& session = channelContext->session; auto& connection = channelContext->connection; status_t status = session->state()->drainCommands(connection, session, RpcState::CommandType::ANY); if (status != OK) { if (status != OK) { LOG_RPC_DETAIL("Binder connection thread closing w/ status %s", LOG_RPC_DETAIL("Binder connection thread closing w/ status %s", statusToString(status).c_str()); statusToString(status).c_str()); Loading @@ -133,10 +147,17 @@ int RpcServerTrusty::handleMessage(const tipc_port* port, handle_t chan, void* c void RpcServerTrusty::handleDisconnect(const tipc_port* port, handle_t chan, void* ctx) {} void RpcServerTrusty::handleDisconnect(const tipc_port* port, handle_t chan, void* ctx) {} void RpcServerTrusty::handleChannelCleanup(void* ctx) { void RpcServerTrusty::handleChannelCleanup(void* ctx) { auto* session = reinterpret_cast<RpcSession*>(ctx); auto* channelContext = reinterpret_cast<ChannelContext*>(ctx); auto& connection = session->mConnections.mIncoming.at(0); if (channelContext == nullptr) { return; } auto& session = channelContext->session; auto& connection = channelContext->connection; LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection), LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection), "bad state: connection object guaranteed to be in list"); "bad state: connection object guaranteed to be in list"); delete channelContext; } } } // namespace android } // namespace android libs/binder/trusty/include/binder/RpcServerTrusty.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -77,6 +77,12 @@ private: explicit RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName, explicit RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName, std::shared_ptr<const PortAcl>&& portAcl, size_t msgMaxSize); std::shared_ptr<const PortAcl>&& portAcl, size_t msgMaxSize); // The Rpc-specific context maintained for every open TIPC channel. struct ChannelContext { sp<RpcSession> session; sp<RpcSession::RpcConnection> connection; }; static int handleConnect(const tipc_port* port, handle_t chan, const uuid* peer, void** ctx_p); static int handleConnect(const tipc_port* port, handle_t chan, const uuid* peer, void** ctx_p); static int handleMessage(const tipc_port* port, handle_t chan, void* ctx); static int handleMessage(const tipc_port* port, handle_t chan, void* ctx); static void handleDisconnect(const tipc_port* port, handle_t chan, void* ctx); static void handleDisconnect(const tipc_port* port, handle_t chan, void* ctx); Loading Loading
libs/binder/trusty/README.md +39 −33 Original line number Original line Diff line number Diff line # Binder for Trusty # Binder for Trusty This is the Trusty port of the libbinder library. This is the Trusty port of the libbinder library. To build it, take the following steps: To build it, first you will need a checkout of the Trusty tree: * Check out copies of the Trusty and AOSP repositories. * Apply the patches from the `trusty_binder` topic on both repositories. * Build Trusty normally using `build.py`. * Run the sample AIDL test for Trusty: ```shell ```shell $ ./build-root/.../run --headless --boot-test com.android.trusty.aidl.test $ mkdir /path/to/trusty $ cd /path/to/trusty $ repo init -u https://android.googlesource.com/trusty/manifest -b master $ repo sync -j$(nproc) -c --no-tags ``` ``` To run the Android-Trusty IPC test, do the following: After the checkout is complete, you can use the `build.py` script for both building and testing Trusty. For a quick build without any tests, run: * Build AOSP for the `qemu_trusty_arm64-userdebug` target: ```shell ```shell $ lunch qemu_trusty_arm64-userdebug $ ./trusty/vendor/google/aosp/scripts/build.py generic-arm64-test-debug $ m ``` ``` * In the Trusty directory, run the emulator with the newly built Android: This will build the smaller `generic-arm64-test-debug` project which does not run any tests. The qemu-generic-arm64-test-debug` project includes the QEMU emulator and a full Trusty test suite, including a set of libbinder tests. To run the latter, use the command: ```shell ```shell $ ./build-root/.../run --android /path/to/aosp $ ./trusty/vendor/google/aosp/scripts/build.py \ --test "boot-test:com.android.trusty.binder.test" \ qemu-generic-arm64-test-debug ``` ``` * Using either `adb` or the shell inside the emulator itself, run the Trusty Binder test as root: ## Building AIDL files on Trusty ```shell To compile AIDL interfaces into Trusty libraries, include the `make/aidl.mk` # /data/nativetest64/vendor/trusty_binder_test/trusty_binder_test in your `rules.mk` file, e.g.: ``` ``` LOCAL_DIR := $(GET_LOCAL_DIR) ## Running the AIDL compiler MODULE := $(LOCAL_DIR) For now, you will need to run the AIDL compiler manually to generate the C++ source code for Trusty clients and services. The general syntax is: MODULE_AIDLS := \ ```shell $(LOCAL_DIR)/IFoo.aidl \ $ aidl --lang=cpp -o <output directory> -h <output header directory> <AIDL files...> include make/aidl.mk ``` ``` The compiler will emit some `.cpp` files in the output directory and their ## Examples corresponding `.h` files in the header directory. The Trusty tree contains some sample test apps at `trusty/user/app/sample/binder-test`.
libs/binder/trusty/RpcServerTrusty.cpp +28 −7 Original line number Original line Diff line number Diff line Loading @@ -104,8 +104,17 @@ int RpcServerTrusty::handleConnect(const tipc_port* port, handle_t chan, const u return; return; } } /* Save the session for easy access */ /* Save the session and connection for the other callbacks */ *ctx_p = session.get(); auto* channelContext = new (std::nothrow) ChannelContext; if (channelContext == nullptr) { rc = ERR_NO_MEMORY; return; } channelContext->session = std::move(session); channelContext->connection = std::move(result.connection); *ctx_p = channelContext; }; }; base::unique_fd clientFd(chan); base::unique_fd clientFd(chan); Loading @@ -119,9 +128,14 @@ int RpcServerTrusty::handleConnect(const tipc_port* port, handle_t chan, const u } } int RpcServerTrusty::handleMessage(const tipc_port* port, handle_t chan, void* ctx) { int RpcServerTrusty::handleMessage(const tipc_port* port, handle_t chan, void* ctx) { auto* session = reinterpret_cast<RpcSession*>(ctx); auto* channelContext = reinterpret_cast<ChannelContext*>(ctx); status_t status = session->state()->drainCommands(session->mConnections.mIncoming[0], session, LOG_ALWAYS_FATAL_IF(channelContext == nullptr, RpcState::CommandType::ANY); "bad state: message received on uninitialized channel"); auto& session = channelContext->session; auto& connection = channelContext->connection; status_t status = session->state()->drainCommands(connection, session, RpcState::CommandType::ANY); if (status != OK) { if (status != OK) { LOG_RPC_DETAIL("Binder connection thread closing w/ status %s", LOG_RPC_DETAIL("Binder connection thread closing w/ status %s", statusToString(status).c_str()); statusToString(status).c_str()); Loading @@ -133,10 +147,17 @@ int RpcServerTrusty::handleMessage(const tipc_port* port, handle_t chan, void* c void RpcServerTrusty::handleDisconnect(const tipc_port* port, handle_t chan, void* ctx) {} void RpcServerTrusty::handleDisconnect(const tipc_port* port, handle_t chan, void* ctx) {} void RpcServerTrusty::handleChannelCleanup(void* ctx) { void RpcServerTrusty::handleChannelCleanup(void* ctx) { auto* session = reinterpret_cast<RpcSession*>(ctx); auto* channelContext = reinterpret_cast<ChannelContext*>(ctx); auto& connection = session->mConnections.mIncoming.at(0); if (channelContext == nullptr) { return; } auto& session = channelContext->session; auto& connection = channelContext->connection; LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection), LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection), "bad state: connection object guaranteed to be in list"); "bad state: connection object guaranteed to be in list"); delete channelContext; } } } // namespace android } // namespace android
libs/binder/trusty/include/binder/RpcServerTrusty.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -77,6 +77,12 @@ private: explicit RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName, explicit RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName, std::shared_ptr<const PortAcl>&& portAcl, size_t msgMaxSize); std::shared_ptr<const PortAcl>&& portAcl, size_t msgMaxSize); // The Rpc-specific context maintained for every open TIPC channel. struct ChannelContext { sp<RpcSession> session; sp<RpcSession::RpcConnection> connection; }; static int handleConnect(const tipc_port* port, handle_t chan, const uuid* peer, void** ctx_p); static int handleConnect(const tipc_port* port, handle_t chan, const uuid* peer, void** ctx_p); static int handleMessage(const tipc_port* port, handle_t chan, void* ctx); static int handleMessage(const tipc_port* port, handle_t chan, void* ctx); static void handleDisconnect(const tipc_port* port, handle_t chan, void* ctx); static void handleDisconnect(const tipc_port* port, handle_t chan, void* ctx); Loading