diff options
| -rw-r--r-- | libs/binder/Binder.cpp | 8 | ||||
| -rw-r--r-- | libs/binder/tests/binderRpcTest.cpp | 102 | ||||
| -rw-r--r-- | libs/binder/trusty/README.md | 72 | ||||
| -rw-r--r-- | libs/binder/trusty/RpcServerTrusty.cpp | 35 | ||||
| -rw-r--r-- | libs/binder/trusty/include/binder/RpcServerTrusty.h | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/RefreshRateOverlay_test.cpp | 8 |
6 files changed, 127 insertions, 104 deletions
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp index 1dc62334cb..402995717c 100644 --- a/libs/binder/Binder.cpp +++ b/libs/binder/Binder.cpp @@ -283,11 +283,9 @@ status_t BBinder::pingBinder() const String16& BBinder::getInterfaceDescriptor() const { - // This is a local static rather than a global static, - // to avoid static initializer ordering issues. - static String16 sEmptyDescriptor; - ALOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this); - return sEmptyDescriptor; + static StaticString16 sBBinder(u"BBinder"); + ALOGW("Reached BBinder::getInterfaceDescriptor (this=%p). Override?", this); + return sBBinder; } // NOLINTNEXTLINE(google-default-arguments) diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp index b59308c156..4c037b77db 100644 --- a/libs/binder/tests/binderRpcTest.cpp +++ b/libs/binder/tests/binderRpcTest.cpp @@ -54,27 +54,6 @@ TEST(BinderRpcParcel, EntireParcelFormatted) { EXPECT_DEATH(p.markForBinder(sp<BBinder>::make()), "format must be set before data is written"); } -class BinderRpcServerOnly : public ::testing::TestWithParam<std::tuple<RpcSecurity, uint32_t>> { -public: - static std::string PrintTestParam(const ::testing::TestParamInfo<ParamType>& info) { - return std::string(newFactory(std::get<0>(info.param))->toCString()) + "_serverV" + - std::to_string(std::get<1>(info.param)); - } -}; - -TEST_P(BinderRpcServerOnly, SetExternalServerTest) { - base::unique_fd sink(TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR))); - int sinkFd = sink.get(); - auto server = RpcServer::make(newFactory(std::get<0>(GetParam()))); - server->setProtocolVersion(std::get<1>(GetParam())); - ASSERT_FALSE(server->hasServer()); - ASSERT_EQ(OK, server->setupExternalServer(std::move(sink))); - ASSERT_TRUE(server->hasServer()); - base::unique_fd retrieved = server->releaseServer(); - ASSERT_FALSE(server->hasServer()); - ASSERT_EQ(sinkFd, retrieved.get()); -} - TEST(BinderRpc, CannotUseNextWireVersion) { auto session = RpcSession::make(); EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT)); @@ -1619,36 +1598,6 @@ private: bool mValue = false; }; -TEST_P(BinderRpcServerOnly, Shutdown) { - if constexpr (!kEnableRpcThreads) { - GTEST_SKIP() << "Test skipped because threads were disabled at build time"; - } - - auto addr = allocateSocketAddress(); - auto server = RpcServer::make(newFactory(std::get<0>(GetParam()))); - server->setProtocolVersion(std::get<1>(GetParam())); - ASSERT_EQ(OK, server->setupUnixDomainServer(addr.c_str())); - auto joinEnds = std::make_shared<OneOffSignal>(); - - // If things are broken and the thread never stops, don't block other tests. Because the thread - // may run after the test finishes, it must not access the stack memory of the test. Hence, - // shared pointers are passed. - std::thread([server, joinEnds] { - server->join(); - joinEnds->notify(); - }).detach(); - - bool shutdown = false; - for (int i = 0; i < 10 && !shutdown; i++) { - usleep(300 * 1000); // 300ms; total 3s - if (server->shutdown()) shutdown = true; - } - ASSERT_TRUE(shutdown) << "server->shutdown() never returns true"; - - ASSERT_TRUE(joinEnds->wait(2s)) - << "After server->shutdown() returns true, join() did not stop after 2s"; -} - TEST(BinderRpc, Java) { #if !defined(__ANDROID__) GTEST_SKIP() << "This test is only run on Android. Though it can technically run on host on" @@ -1701,6 +1650,57 @@ TEST(BinderRpc, Java) { ASSERT_EQ(OK, rpcBinder->pingBinder()); } +class BinderRpcServerOnly : public ::testing::TestWithParam<std::tuple<RpcSecurity, uint32_t>> { +public: + static std::string PrintTestParam(const ::testing::TestParamInfo<ParamType>& info) { + return std::string(newFactory(std::get<0>(info.param))->toCString()) + "_serverV" + + std::to_string(std::get<1>(info.param)); + } +}; + +TEST_P(BinderRpcServerOnly, SetExternalServerTest) { + base::unique_fd sink(TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR))); + int sinkFd = sink.get(); + auto server = RpcServer::make(newFactory(std::get<0>(GetParam()))); + server->setProtocolVersion(std::get<1>(GetParam())); + ASSERT_FALSE(server->hasServer()); + ASSERT_EQ(OK, server->setupExternalServer(std::move(sink))); + ASSERT_TRUE(server->hasServer()); + base::unique_fd retrieved = server->releaseServer(); + ASSERT_FALSE(server->hasServer()); + ASSERT_EQ(sinkFd, retrieved.get()); +} + +TEST_P(BinderRpcServerOnly, Shutdown) { + if constexpr (!kEnableRpcThreads) { + GTEST_SKIP() << "Test skipped because threads were disabled at build time"; + } + + auto addr = allocateSocketAddress(); + auto server = RpcServer::make(newFactory(std::get<0>(GetParam()))); + server->setProtocolVersion(std::get<1>(GetParam())); + ASSERT_EQ(OK, server->setupUnixDomainServer(addr.c_str())); + auto joinEnds = std::make_shared<OneOffSignal>(); + + // If things are broken and the thread never stops, don't block other tests. Because the thread + // may run after the test finishes, it must not access the stack memory of the test. Hence, + // shared pointers are passed. + std::thread([server, joinEnds] { + server->join(); + joinEnds->notify(); + }).detach(); + + bool shutdown = false; + for (int i = 0; i < 10 && !shutdown; i++) { + usleep(300 * 1000); // 300ms; total 3s + if (server->shutdown()) shutdown = true; + } + ASSERT_TRUE(shutdown) << "server->shutdown() never returns true"; + + ASSERT_TRUE(joinEnds->wait(2s)) + << "After server->shutdown() returns true, join() did not stop after 2s"; +} + INSTANTIATE_TEST_CASE_P(BinderRpc, BinderRpcServerOnly, ::testing::Combine(::testing::ValuesIn(RpcSecurityValues()), ::testing::ValuesIn(testVersions())), diff --git a/libs/binder/trusty/README.md b/libs/binder/trusty/README.md index 1a273aab10..8a60af8b23 100644 --- a/libs/binder/trusty/README.md +++ b/libs/binder/trusty/README.md @@ -1,39 +1,45 @@ # Binder for Trusty This is the Trusty port of the libbinder library. -To build it, take the following steps: - -* 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 - $ ./build-root/.../run --headless --boot-test com.android.trusty.aidl.test - ``` - -To run the Android-Trusty IPC test, do the following: - -* Build AOSP for the `qemu_trusty_arm64-userdebug` target: - ```shell - $ lunch qemu_trusty_arm64-userdebug - $ m - ``` -* In the Trusty directory, run the emulator with the newly built Android: - ```shell - $ ./build-root/.../run --android /path/to/aosp - ``` -* Using either `adb` or the shell inside the emulator itself, run the Trusty - Binder test as root: - ```shell - # /data/nativetest64/vendor/trusty_binder_test/trusty_binder_test - ``` - -## Running the AIDL compiler -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: +To build it, first you will need a checkout of the Trusty tree: ```shell -$ aidl --lang=cpp -o <output directory> -h <output header directory> <AIDL files...> +$ 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 ``` -The compiler will emit some `.cpp` files in the output directory and their -corresponding `.h` files in the header directory. +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: +```shell +$ ./trusty/vendor/google/aosp/scripts/build.py generic-arm64-test-debug +``` +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 +$ ./trusty/vendor/google/aosp/scripts/build.py \ + --test "boot-test:com.android.trusty.binder.test" \ + qemu-generic-arm64-test-debug +``` + +## Building AIDL files on Trusty +To compile AIDL interfaces into Trusty libraries, include the `make/aidl.mk` +in your `rules.mk` file, e.g.: +``` +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULE := $(LOCAL_DIR) + +MODULE_AIDLS := \ + $(LOCAL_DIR)/IFoo.aidl \ + +include make/aidl.mk +``` + +## Examples +The Trusty tree contains some sample test apps at +`trusty/user/app/sample/binder-test`. diff --git a/libs/binder/trusty/RpcServerTrusty.cpp b/libs/binder/trusty/RpcServerTrusty.cpp index e8b91e7a4c..c789614c0b 100644 --- a/libs/binder/trusty/RpcServerTrusty.cpp +++ b/libs/binder/trusty/RpcServerTrusty.cpp @@ -104,8 +104,17 @@ int RpcServerTrusty::handleConnect(const tipc_port* port, handle_t chan, const u return; } - /* Save the session for easy access */ - *ctx_p = session.get(); + /* Save the session and connection for the other callbacks */ + 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); @@ -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) { - auto* session = reinterpret_cast<RpcSession*>(ctx); - status_t status = session->state()->drainCommands(session->mConnections.mIncoming[0], session, - RpcState::CommandType::ANY); + auto* channelContext = reinterpret_cast<ChannelContext*>(ctx); + LOG_ALWAYS_FATAL_IF(channelContext == nullptr, + "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) { LOG_RPC_DETAIL("Binder connection thread closing w/ status %s", statusToString(status).c_str()); @@ -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::handleChannelCleanup(void* ctx) { - auto* session = reinterpret_cast<RpcSession*>(ctx); - auto& connection = session->mConnections.mIncoming.at(0); + auto* channelContext = reinterpret_cast<ChannelContext*>(ctx); + if (channelContext == nullptr) { + return; + } + + auto& session = channelContext->session; + auto& connection = channelContext->connection; LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection), "bad state: connection object guaranteed to be in list"); + + delete channelContext; } } // namespace android diff --git a/libs/binder/trusty/include/binder/RpcServerTrusty.h b/libs/binder/trusty/include/binder/RpcServerTrusty.h index e8fc9f988d..cc31c95da1 100644 --- a/libs/binder/trusty/include/binder/RpcServerTrusty.h +++ b/libs/binder/trusty/include/binder/RpcServerTrusty.h @@ -77,6 +77,12 @@ private: explicit RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName, 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 handleMessage(const tipc_port* port, handle_t chan, void* ctx); static void handleDisconnect(const tipc_port* port, handle_t chan, void* ctx); diff --git a/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp b/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp index fb4458a27e..916267447b 100644 --- a/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp +++ b/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp @@ -80,14 +80,6 @@ void toggleOverlay(bool enabled) { } // namespace -TEST(RefreshRateOverlayTest, enableOverlay) { - toggleOverlay(true); -} - -TEST(RefreshRateOverlayTest, disableOverlay) { - toggleOverlay(false); -} - TEST(RefreshRateOverlayTest, enableAndDisableOverlay) { toggleOverlay(true); toggleOverlay(false); |