summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Henri Chataing <henrichataing@google.com> 2024-10-25 17:04:33 -0700
committer Henri Chataing <henrichataing@google.com> 2024-10-29 17:45:09 +0000
commit8f33f462daaee6c906a6fcf26f28c4fca32425d1 (patch)
tree2bdf46eaa09692608c9febdb87e0d206bf5081af
parenta8eeda6cd6cf1f19a23f6cff813ea169c995559e (diff)
Remove libbluetooth-gdx
ModuleMainloop, ModuleJniloop are thin wrappers on top of do_in_main_thread, do_in_jni_thread, and are only used in tests. Remove the associated tests libbluetooth-gdx-test for dumpsys and lifecylce due to lack of comment and documentation (only run in postsubmit). Bug: 331817295 Test: m com.android.btservices Flag: EXEMPT, dead code removal Change-Id: I84d810e3f5a371013e1cc3a17561ccaa66f65164
-rw-r--r--TEST_MAPPING3
-rw-r--r--android/app/Android.bp1
-rw-r--r--system/audio_hal_interface/Android.bp1
-rw-r--r--system/audio_hal_interface/fuzzer/Android.bp1
-rw-r--r--system/btif/Android.bp1
-rw-r--r--system/btif/BUILD.gn1
-rw-r--r--system/gd/Android.bp84
-rw-r--r--system/gd/BUILD.gn11
-rw-r--r--system/gd/module_gdx_unittest.cc623
-rw-r--r--system/gd/module_gdx_unittest.h78
-rw-r--r--system/gd/module_jniloop.h53
-rw-r--r--system/gd/module_jniloop_unittest.cc244
-rw-r--r--system/gd/module_jniloop_unittest.h57
-rw-r--r--system/gd/module_mainloop.h53
-rw-r--r--system/gd/module_mainloop_unittest.cc245
-rw-r--r--system/gd/module_mainloop_unittest.h57
-rw-r--r--system/gd/module_state_dumper_unittest.cc161
-rw-r--r--system/gd/module_state_dumper_unittest.h46
-rw-r--r--system/gd/rust/topshim/facade/Android.bp1
-rw-r--r--system/main/Android.bp104
-rw-r--r--system/main/test/main_shim_stack_dumpsys_test.cc643
-rw-r--r--system/main/test/main_shim_stack_lifecycle_test.cc619
-rw-r--r--system/stack/Android.bp1
-rw-r--r--system/stack/test/fuzzers/Android.bp1
-rw-r--r--system/test/headless/Android.bp1
-rw-r--r--system/test/suite/Android.bp1
26 files changed, 3 insertions, 3088 deletions
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 5da35c4dc0..bd98b7d91c 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -308,9 +308,6 @@
"name": "bluetooth-test-audio-hal-a2dp-provider-info"
},
{
- "name": "bluetooth_test_gdx_unit"
- },
- {
"name": "net_test_bta_jv"
},
{
diff --git a/android/app/Android.bp b/android/app/Android.bp
index f038a3f43b..2bac3ba017 100644
--- a/android/app/Android.bp
+++ b/android/app/Android.bp
@@ -106,7 +106,6 @@ cc_library_shared {
"libbase",
"libbluetooth",
"libbluetooth-dumpsys",
- "libbluetooth-gdx",
"libbluetooth-types",
"libbluetooth_core_rs",
"libbluetooth_core_rs_bridge",
diff --git a/system/audio_hal_interface/Android.bp b/system/audio_hal_interface/Android.bp
index 1e5652c747..987b859214 100644
--- a/system/audio_hal_interface/Android.bp
+++ b/system/audio_hal_interface/Android.bp
@@ -228,7 +228,6 @@ cc_defaults {
"libFraunhoferAAC",
"libbase",
"libbluetooth-dumpsys",
- "libbluetooth-gdx",
"libbluetooth-protos",
"libbluetooth-types",
"libbluetooth_core_rs",
diff --git a/system/audio_hal_interface/fuzzer/Android.bp b/system/audio_hal_interface/fuzzer/Android.bp
index e55a9d62ad..93a734b02f 100644
--- a/system/audio_hal_interface/fuzzer/Android.bp
+++ b/system/audio_hal_interface/fuzzer/Android.bp
@@ -60,7 +60,6 @@ cc_defaults {
"libFraunhoferAAC",
"libbase",
"libbluetooth-dumpsys",
- "libbluetooth-gdx",
"libbluetooth-protos",
"libbluetooth-types",
"libbluetooth_core_rs",
diff --git a/system/btif/Android.bp b/system/btif/Android.bp
index 2d3d40e3fd..2402f95c07 100644
--- a/system/btif/Android.bp
+++ b/system/btif/Android.bp
@@ -298,7 +298,6 @@ cc_test {
"libbase",
"libbluetooth-dumpsys",
"libbluetooth-for-tests",
- "libbluetooth-gdx",
"libbluetooth-types",
"libbluetooth_core_rs",
"libbluetooth_crypto_toolbox",
diff --git a/system/btif/BUILD.gn b/system/btif/BUILD.gn
index 5129a1efb3..884dc60ba3 100644
--- a/system/btif/BUILD.gn
+++ b/system/btif/BUILD.gn
@@ -114,7 +114,6 @@ static_library("btif") {
"//bt/system:libbt-platform-protos-lite",
"//bt/system/common",
"//bt/system/profile/avrcp:profile_avrcp",
- "//bt/system/gd:libbluetooth-gdx",
]
configs += [
diff --git a/system/gd/Android.bp b/system/gd/Android.bp
index 579aae7d44..c74cff9adb 100644
--- a/system/gd/Android.bp
+++ b/system/gd/Android.bp
@@ -129,6 +129,7 @@ cc_defaults {
":BluetoothNeighborSources",
":BluetoothOsSources",
":BluetoothPacketSources",
+ ":BluetoothShimSources",
":BluetoothStorageSources",
"module.cc",
"module_dumper.cc",
@@ -173,7 +174,7 @@ cc_defaults {
],
}
-cc_library {
+cc_library_static {
name: "libbluetooth_gd",
defaults: [
"libbluetooth_gd_defaults",
@@ -192,27 +193,6 @@ cc_library {
}
cc_library_static {
- name: "libbluetooth-gdx",
- defaults: [
- "libbluetooth_gd_defaults",
- ],
- srcs: [
- ":BluetoothShimSources",
- ],
- include_dirs: [
- "packages/modules/Bluetooth/system",
- ],
- apex_available: [
- "com.android.btservices",
- ],
- min_sdk_version: "31",
- static_libs: [
- "bluetooth_flags_c_lib",
- "libchrome",
- ],
-}
-
-cc_library {
name: "libbluetooth_gd_fuzzing",
defaults: [
"libbluetooth_gd_defaults",
@@ -236,7 +216,7 @@ cc_library {
],
}
-cc_library {
+cc_library_static {
name: "libbluetooth_gd_unit_tests",
defaults: [
"libbluetooth_gd_defaults",
@@ -297,7 +277,6 @@ cc_binary {
"breakpad_client",
"libPlatformProperties",
"libbluetooth-dumpsys",
- "libbluetooth-gdx",
"libbluetooth-protos",
"libbluetooth-types",
"libbluetooth_crypto_toolbox",
@@ -498,63 +477,6 @@ cc_test {
}
cc_test {
- name: "bluetooth_test_gdx_unit",
- test_suites: ["device-tests"],
- defaults: [
- "aconfig_lib_cc_shared_link.defaults",
- "gd_defaults",
- "mts_defaults",
- ],
- include_dirs: [
- "packages/modules/Bluetooth/system",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/stack/include",
- "packages/modules/Bluetooth/system/types",
- ],
- host_supported: true,
- srcs: [
- ":BluetoothDumpsysTestSources",
- ":BluetoothShimTestSources",
- ":TestCommonMockFunctions",
- ":TestMockMainShimStack",
- "module_gdx_unittest.cc",
- "module_jniloop_unittest.cc",
- "module_mainloop_unittest.cc",
- "module_state_dumper_unittest.cc",
- ],
- generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
- "BluetoothGeneratedDumpsysDataSchema_h",
- "BluetoothGeneratedDumpsysInternalTestData_h",
- "BluetoothGeneratedDumpsysTestData_h",
- ],
- static_libs: [
- "bluetooth_flags_c_lib_for_test",
- "libbase",
- "libbluetooth-dumpsys",
- "libbluetooth-dumpsys-test",
- "libbluetooth-dumpsys-unittest",
- "libbluetooth-gdx",
- "libbluetooth_gd",
- "libbluetooth_log",
- "libbt-btu-main-thread",
- "libbt-common",
- "libbt-jni-thread",
- "libchrome",
- "libevent",
- "libflatbuffers-cpp",
- "libgmock",
- "liblog",
- "libosi",
- "server_configurable_flags",
- ],
- sanitize: {
- address: true,
- },
- min_sdk_version: "Tiramisu",
-}
-
-cc_test {
name: "bluetooth_packet_parser_test",
test_suites: ["general-tests"],
defaults: [
diff --git a/system/gd/BUILD.gn b/system/gd/BUILD.gn
index 5786a5b700..fa8a64fd25 100644
--- a/system/gd/BUILD.gn
+++ b/system/gd/BUILD.gn
@@ -53,17 +53,6 @@ group("gd_default_deps") {
]
}
-static_library("libbluetooth-gdx") {
- include_dirs = [
- "packages/modules/Bluetooth/system",
- ]
- configs += [ ":gd_defaults" ]
- deps = [
- "//bt/system/gd:gd_default_deps",
- "//bt/system/gd/shim:BluetoothShimSources",
- ]
-}
-
static_library("libbluetooth_gd") {
sources = [
"module.cc",
diff --git a/system/gd/module_gdx_unittest.cc b/system/gd/module_gdx_unittest.cc
deleted file mode 100644
index 9d9ee4c7c8..0000000000
--- a/system/gd/module_gdx_unittest.cc
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "module_gdx_unittest.h"
-
-#include <base/callback.h>
-#include <base/functional/bind.h>
-#include <base/location.h>
-#include <base/threading/platform_thread.h>
-#include <sys/syscall.h>
-
-#include <chrono>
-#include <future>
-#include <string>
-
-#include "common/bind.h"
-#include "common/contextual_callback.h"
-#include "gtest/gtest.h"
-#include "module.h"
-#include "os/handler.h"
-
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
-using namespace bluetooth;
-
-namespace {
-constexpr int sync_timeout_in_ms = 3000;
-
-std::promise<pid_t> gdx_external_function_promise;
-std::promise<pid_t> private_impl_promise;
-std::promise<pid_t> protected_method_promise;
-
-} // namespace
-
-// Global function with C linkage
-void external_function_gdx(int /* a */, double /* b */, char /* c */) {
- gdx_external_function_promise.set_value(base::PlatformThread::CurrentId());
-}
-
-// Module private implementation that is inaccessible externally
-struct TestGdxModule::PrivateImpl : public ModuleMainloop, public ModuleJniloop {
- const int kMaxTestGdxModuleRecurseDepth = 10;
-
- void privateCallableMethod(int /* a */, double /* b */, char /* c */) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- }
-
- void repostMethodTest(int /* a */, double /* b */, char /* c */) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- }
-
- void privateCallableRepostOnMainMethod(std::shared_ptr<TestGdxModule::PrivateImpl> ptr, int a,
- double b, char c) {
- PostMethodOnMain(ptr, &PrivateImpl::repostMethodTest, a, b, c);
- }
-
- void privateCallableRepostOnJniMethod(std::shared_ptr<TestGdxModule::PrivateImpl> ptr, int a,
- double b, char c) {
- PostMethodOnJni(ptr, &PrivateImpl::repostMethodTest, a, b, c);
- }
-
- void privateCallableRecursiveOnMainMethod(std::shared_ptr<TestGdxModule::PrivateImpl> ptr,
- int depth, double b, char c) {
- if (depth > kMaxTestGdxModuleRecurseDepth) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- return;
- }
- PostMethodOnMain(ptr, &PrivateImpl::privateCallableRecursiveOnMainMethod, ptr, depth + 1, b, c);
- }
-
- void privateCallableRecursiveOnJniMethod(std::shared_ptr<TestGdxModule::PrivateImpl> ptr,
- int depth, double b, char c) {
- if (depth > kMaxTestGdxModuleRecurseDepth) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- return;
- }
- PostMethodOnJni(ptr, &PrivateImpl::privateCallableRecursiveOnJniMethod, ptr, depth + 1, b, c);
- }
-};
-
-// Protected module method executed on handler
-void TestGdxModule::call_on_handler_protected_method(int loop_tid, int a, int b, int c) {
- protected_method_promise = std::promise<pid_t>();
- auto future = protected_method_promise.get_future();
- CallOn(this, &TestGdxModule::protected_method, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Global external function executed on main loop
-void TestGdxModule::call_on_main_external_function(int loop_tid, int a, double b, char c) {
- gdx_external_function_promise = std::promise<pid_t>();
- auto future = gdx_external_function_promise.get_future();
- PostFunctionOnMain(&external_function_gdx, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop
-void TestGdxModule::call_on_main(int loop_tid, int a, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnMain(pimpl_, &TestGdxModule::PrivateImpl::privateCallableMethod, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop and reposted
-void TestGdxModule::call_on_main_repost(int loop_tid, int a, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnMain(pimpl_, &TestGdxModule::PrivateImpl::privateCallableRepostOnMainMethod, pimpl_,
- a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop recursively
-void TestGdxModule::call_on_main_recurse(int loop_tid, int depth, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnMain(pimpl_, &TestGdxModule::PrivateImpl::privateCallableRecursiveOnMainMethod,
- pimpl_, depth, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Global external function executed on main loop
-void TestGdxModule::call_on_jni_external_function(int loop_tid, int a, double b, char c) {
- gdx_external_function_promise = std::promise<pid_t>();
- auto future = gdx_external_function_promise.get_future();
- PostFunctionOnJni(&external_function_gdx, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop
-void TestGdxModule::call_on_jni(int loop_tid, int a, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnJni(pimpl_, &TestGdxModule::PrivateImpl::privateCallableMethod, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop and reposted
-void TestGdxModule::call_on_jni_repost(int loop_tid, int a, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnJni(pimpl_, &TestGdxModule::PrivateImpl::privateCallableRepostOnJniMethod, pimpl_, a,
- b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop recursively
-void TestGdxModule::call_on_jni_recurse(int loop_tid, int depth, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnJni(pimpl_, &TestGdxModule::PrivateImpl::privateCallableRecursiveOnJniMethod, pimpl_,
- depth, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-void TestGdxModule::protected_method(int /* a */, int /* b */, int /* c */) {
- protected_method_promise.set_value(base::PlatformThread::CurrentId());
-}
-
-bool TestGdxModule::IsStarted() const { return pimpl_ != nullptr; }
-
-void TestGdxModule::Start() {
- ASSERT_FALSE(IsStarted());
- pimpl_ = std::make_shared<TestGdxModule::PrivateImpl>();
-}
-
-void TestGdxModule::Stop() {
- ASSERT_TRUE(IsStarted());
- pimpl_.reset();
-}
-
-std::string TestGdxModule::ToString() const { return "TestGdxModule"; }
-
-const bluetooth::ModuleFactory TestGdxModule::Factory =
- bluetooth::ModuleFactory([]() { return new TestGdxModule(); });
-
-void TestGdxModule::set_callback(common::ContextualCallback<void(std::string)> callback) {
- call_many_ = callback;
-}
-
-void TestGdxModule::set_once_callback(common::ContextualOnceCallback<void(std::string)> callback) {
- call_once_ = std::move(callback);
-}
-
-void TestGdxModule::call_callback_on_handler(std::string message) {
- GetHandler()->Post(common::BindOnce([](common::ContextualCallback<void(std::string)> callback,
- std::string message) { callback(message); },
- call_many_, message));
-}
-
-void TestGdxModule::call_once_callback_on_handler(std::string message) {
- GetHandler()->Post(common::BindOnce([](common::ContextualOnceCallback<void(std::string)> callback,
- std::string message) { callback(message); },
- std::move(call_once_), message));
-}
-
-void TestGdxModule::call_callback_on_main(std::string message) {
- post_on_bt_main([message, this]() { call_many_(message); });
-}
-
-void TestGdxModule::call_once_callback_on_main(std::string message) {
- post_on_bt_main([message, this]() { call_once_(message); });
-}
-
-void TestGdxModule::call_callback_on_jni(std::string message) {
- post_on_bt_jni([message, this]() { call_many_(message); });
-}
-
-void TestGdxModule::call_once_callback_on_jni(std::string message) {
- post_on_bt_jni([message, this]() { call_once_(message); });
-}
-
-//
-// Module GDx Testing Below
-//
-class ModuleGdxTest : public ::testing::Test {
-protected:
- void SetUp() override {
- test_framework_tid_ = base::PlatformThread::CurrentId();
- module_ = new TestGdxModule();
- main_thread_start_up();
- mainloop_tid_ = get_mainloop_tid();
- jni_thread_startup();
- jniloop_tid_ = get_jniloop_tid();
- }
-
- void TearDown() override {
- sync_main_handler();
- main_thread_shut_down();
- jni_thread_shutdown();
- delete module_;
- }
-
- void sync_main_handler() {
- std::promise promise = std::promise<void>();
- std::future future = promise.get_future();
- post_on_bt_main([&promise]() { promise.set_value(); });
- future.wait_for(std::chrono::milliseconds(sync_timeout_in_ms));
- }
-
- void sync_jni_handler() {
- std::promise promise = std::promise<void>();
- std::future future = promise.get_future();
- post_on_bt_jni([&promise]() { promise.set_value(); });
- future.wait_for(std::chrono::milliseconds(sync_timeout_in_ms));
- }
-
- static pid_t get_mainloop_tid() {
- std::promise<pid_t> pid_promise = std::promise<pid_t>();
- auto future = pid_promise.get_future();
- post_on_bt_main([&pid_promise]() { pid_promise.set_value(base::PlatformThread::CurrentId()); });
- return future.get();
- }
-
- static pid_t get_jniloop_tid() {
- std::promise<pid_t> pid_promise = std::promise<pid_t>();
- auto future = pid_promise.get_future();
- post_on_bt_jni([&pid_promise]() { pid_promise.set_value(base::PlatformThread::CurrentId()); });
- return future.get();
- }
-
- pid_t test_framework_tid_{-1};
- pid_t mainloop_tid_{-1};
- pid_t jniloop_tid_{-1};
- TestModuleRegistry module_registry_;
- TestGdxModule* module_;
-};
-
-class ModuleGdxWithStackTest : public ModuleGdxTest {
-protected:
- void SetUp() override {
- ModuleGdxTest::SetUp();
- module_registry_.InjectTestModule(&TestGdxModule::Factory, module_ /* pass ownership */);
- module_ = nullptr; // ownership is passed
- handler_tid_ = get_handler_tid(module_registry_.GetTestModuleHandler(&TestGdxModule::Factory));
- }
-
- static pid_t get_handler_tid(os::Handler* handler) {
- std::promise<pid_t> handler_tid_promise = std::promise<pid_t>();
- std::future<pid_t> future = handler_tid_promise.get_future();
- handler->Post(common::BindOnce(
- [](std::promise<pid_t> promise) {
- promise.set_value(base::PlatformThread::CurrentId());
- },
- std::move(handler_tid_promise)));
- return future.get();
- }
-
- void TearDown() override {
- module_registry_.StopAll();
- ModuleGdxTest::TearDown();
- }
-
- TestGdxModule* Mod() { return module_registry_.GetModuleUnderTest<TestGdxModule>(); }
-
- pid_t handler_tid_{-1};
-};
-
-TEST_F(ModuleGdxTest, nop) {}
-
-TEST_F(ModuleGdxTest, lifecycle) {
- ::bluetooth::os::Thread* thread =
- new bluetooth::os::Thread("Name", bluetooth::os::Thread::Priority::REAL_TIME);
- ASSERT_FALSE(module_registry_.IsStarted<TestGdxModule>());
- module_registry_.Start<TestGdxModule>(thread);
- ASSERT_TRUE(module_registry_.IsStarted<TestGdxModule>());
- module_registry_.StopAll();
- ASSERT_FALSE(module_registry_.IsStarted<TestGdxModule>());
- delete thread;
-}
-
-// internal handler
-TEST_F(ModuleGdxWithStackTest, call_on_handler_protected_method) {
- Mod()->call_on_handler_protected_method(handler_tid_, 1, 2, 3);
-}
-
-TEST_F(ModuleGdxWithStackTest, test_call_on_main) { Mod()->call_on_main(mainloop_tid_, 1, 2, 3); }
-
-TEST_F(ModuleGdxWithStackTest, test_call_gdx_external_function_on_main) {
- Mod()->call_on_main_external_function(mainloop_tid_, 1, 2.3, 'c');
-}
-
-TEST_F(ModuleGdxWithStackTest, test_call_on_main_repost) {
- Mod()->call_on_main_repost(mainloop_tid_, 1, 2, 3);
-}
-
-TEST_F(ModuleGdxWithStackTest, test_call_on_main_recurse) {
- Mod()->call_on_main_recurse(mainloop_tid_, 1, 2, 3);
-}
-
-TEST_F(ModuleGdxWithStackTest, test_call_on_jni) { Mod()->call_on_jni(jniloop_tid_, 1, 2, 3); }
-
-TEST_F(ModuleGdxWithStackTest, test_call_gdx_external_function_on_jni) {
- Mod()->call_on_jni_external_function(jniloop_tid_, 1, 2.3, 'c');
-}
-
-TEST_F(ModuleGdxWithStackTest, test_call_on_jni_repost) {
- Mod()->call_on_jni_repost(jniloop_tid_, 1, 2, 3);
-}
-
-TEST_F(ModuleGdxWithStackTest, test_call_on_jni_recurse) {
- Mod()->call_on_jni_recurse(jniloop_tid_, 1, 2, 3);
-}
-
-class ModuleGdxWithInstrumentedCallback : public ModuleGdxWithStackTest {
-protected:
- void SetUp() override { ModuleGdxWithStackTest::SetUp(); }
-
- void TearDown() override { ModuleGdxWithStackTest::TearDown(); }
-
- // A helper class to promise/future for synchronization
- class Promises {
- public:
- std::promise<std::string> result;
- std::future<std::string> result_future = result.get_future();
- std::promise<void> blocking;
- std::future<void> blocking_future = blocking.get_future();
- std::promise<void> unblock;
- std::future<void> unblock_future = unblock.get_future();
- };
-
- class InstrumentedCallback {
- public:
- Promises promises;
- common::ContextualCallback<void(std::string)> callback;
- };
-
- class InstrumentedOnceCallback {
- public:
- Promises promises;
- common::ContextualOnceCallback<void(std::string)> callback;
- };
-
- std::unique_ptr<InstrumentedCallback> GetNewCallbackOnMain() {
- auto to_return = std::make_unique<InstrumentedCallback>();
- to_return->callback = get_main()->Bind(
- [](std::promise<std::string>* promise_ptr, std::promise<void>* blocking,
- std::future<void>* unblock, std::string result) {
- // Tell the test that this callback is running (and blocking)
- blocking->set_value();
- // Block until the test is ready to continue
- ASSERT_EQ(std::future_status::ready, unblock->wait_for(std::chrono::seconds(1)));
- // Send the result back to the test
- promise_ptr->set_value(result);
- log::info("set_value {}", result);
- },
- &to_return->promises.result, &to_return->promises.blocking,
- &to_return->promises.unblock_future);
-
- return to_return;
- }
-
- std::unique_ptr<InstrumentedOnceCallback> GetNewOnceCallbackOnMain() {
- auto to_return = std::make_unique<InstrumentedOnceCallback>();
- to_return->callback = get_main()->BindOnce(
- [](std::promise<std::string>* promise_ptr, std::promise<void>* blocking,
- std::future<void>* unblock, std::string result) {
- blocking->set_value();
- ASSERT_EQ(std::future_status::ready, unblock->wait_for(std::chrono::seconds(1)));
- promise_ptr->set_value(result);
- log::info("set_value {}", result);
- },
- &to_return->promises.result, &to_return->promises.blocking,
- &to_return->promises.unblock_future);
-
- return to_return;
- }
-};
-
-TEST_F(ModuleGdxWithInstrumentedCallback, test_call_callback_on_handler) {
- auto instrumented = GetNewCallbackOnMain();
- Mod()->set_callback(instrumented->callback);
-
- // Enqueue the callback and wait for it to block on main thread
- std::string result = "This was called on the handler";
- Mod()->call_callback_on_handler(result);
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.blocking_future.wait_for(std::chrono::seconds(1)));
- log::info("Waiting");
-
- // Enqueue something else on the main thread and verify that it hasn't run
- static auto second_task_promise = std::promise<void>();
- auto final_future = second_task_promise.get_future();
- do_in_main_thread(common::BindOnce(
- [](std::promise<void> promise) {
- promise.set_value();
- log::info("Finally");
- },
- std::move(second_task_promise)));
- ASSERT_EQ(std::future_status::timeout, final_future.wait_for(std::chrono::milliseconds(1)));
-
- // Let the callback start
- instrumented->promises.unblock.set_value();
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.result_future.wait_for(std::chrono::seconds(1)));
- ASSERT_EQ(result, instrumented->promises.result_future.get());
-
- // Let the second task finish
- ASSERT_EQ(std::future_status::ready, final_future.wait_for(std::chrono::seconds(1)));
-}
-
-TEST_F(ModuleGdxWithInstrumentedCallback, test_call_once_callback_on_handler) {
- auto instrumented = GetNewOnceCallbackOnMain();
- Mod()->set_once_callback(std::move(instrumented->callback));
-
- // Enqueue the callback and wait for it to block on main thread
- std::string result = "This was called on the handler";
- Mod()->call_once_callback_on_handler(result);
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.blocking_future.wait_for(std::chrono::seconds(1)));
- log::info("Waiting");
-
- // Enqueue something else on the main thread and verify that it hasn't run
- static auto second_task_promise = std::promise<void>();
- auto final_future = second_task_promise.get_future();
- do_in_main_thread(common::BindOnce(
- [](std::promise<void> promise) {
- promise.set_value();
- log::info("Finally");
- },
- std::move(second_task_promise)));
- ASSERT_EQ(std::future_status::timeout, final_future.wait_for(std::chrono::milliseconds(1)));
-
- // Let the callback start
- instrumented->promises.unblock.set_value();
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.result_future.wait_for(std::chrono::seconds(1)));
- ASSERT_EQ(result, instrumented->promises.result_future.get());
-
- // Let the second task finish
- ASSERT_EQ(std::future_status::ready, final_future.wait_for(std::chrono::seconds(1)));
-}
-
-TEST_F(ModuleGdxWithInstrumentedCallback, test_call_callback_on_main) {
- auto instrumented = GetNewCallbackOnMain();
- Mod()->set_callback(instrumented->callback);
-
- // Enqueue the callback and wait for it to block on main thread
- std::string result = "This was called on the main";
- Mod()->call_callback_on_main(result);
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.blocking_future.wait_for(std::chrono::seconds(1)));
- log::info("Waiting");
-
- // Enqueue something else on the main thread and verify that it hasn't run
- static auto second_task_promise = std::promise<void>();
- auto final_future = second_task_promise.get_future();
- do_in_main_thread(common::BindOnce(
- [](std::promise<void> promise) {
- promise.set_value();
- log::info("Finally");
- },
- std::move(second_task_promise)));
- ASSERT_EQ(std::future_status::timeout, final_future.wait_for(std::chrono::milliseconds(1)));
-
- // Let the callback start
- instrumented->promises.unblock.set_value();
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.result_future.wait_for(std::chrono::seconds(1)));
- ASSERT_EQ(result, instrumented->promises.result_future.get());
-
- // Let the second task finish
- ASSERT_EQ(std::future_status::ready, final_future.wait_for(std::chrono::seconds(1)));
-}
-
-TEST_F(ModuleGdxWithInstrumentedCallback, test_call_once_callback_on_main) {
- auto instrumented = GetNewOnceCallbackOnMain();
- Mod()->set_once_callback(std::move(instrumented->callback));
-
- // Enqueue the callback and wait for it to block on main thread
- std::string result = "This was called on the main";
- Mod()->call_once_callback_on_main(result);
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.blocking_future.wait_for(std::chrono::seconds(1)));
- log::info("Waiting");
-
- // Enqueue something else on the main thread and verify that it hasn't run
- static auto second_task_promise = std::promise<void>();
- auto final_future = second_task_promise.get_future();
- do_in_main_thread(common::BindOnce(
- [](std::promise<void> promise) {
- promise.set_value();
- log::info("Finally");
- },
- std::move(second_task_promise)));
- ASSERT_EQ(std::future_status::timeout, final_future.wait_for(std::chrono::milliseconds(1)));
-
- // Let the callback start
- instrumented->promises.unblock.set_value();
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.result_future.wait_for(std::chrono::seconds(1)));
- ASSERT_EQ(result, instrumented->promises.result_future.get());
-
- // Let the second task finish
- ASSERT_EQ(std::future_status::ready, final_future.wait_for(std::chrono::seconds(1)));
-}
-
-TEST_F(ModuleGdxWithInstrumentedCallback, test_call_callback_on_jni) {
- auto instrumented = GetNewCallbackOnMain();
- Mod()->set_callback(instrumented->callback);
-
- // Enqueue the callback and wait for it to block on main thread
- std::string result = "This was called on the jni";
- Mod()->call_callback_on_jni(result);
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.blocking_future.wait_for(std::chrono::seconds(1)));
- log::info("Waiting");
-
- // Enqueue something else on the main thread and verify that it hasn't run
- static auto second_task_promise = std::promise<void>();
- auto final_future = second_task_promise.get_future();
- do_in_main_thread(common::BindOnce(
- [](std::promise<void> promise) {
- promise.set_value();
- log::info("Finally");
- },
- std::move(second_task_promise)));
- ASSERT_EQ(std::future_status::timeout, final_future.wait_for(std::chrono::milliseconds(1)));
-
- // Let the callback start
- instrumented->promises.unblock.set_value();
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.result_future.wait_for(std::chrono::seconds(1)));
- ASSERT_EQ(result, instrumented->promises.result_future.get());
-
- // Let the second task finish
- ASSERT_EQ(std::future_status::ready, final_future.wait_for(std::chrono::seconds(1)));
-}
-
-TEST_F(ModuleGdxWithInstrumentedCallback, test_call_once_callback_on_jni) {
- auto instrumented = GetNewOnceCallbackOnMain();
- Mod()->set_once_callback(std::move(instrumented->callback));
-
- // Enqueue the callback and wait for it to block on main thread
- std::string result = "This was called on the jni";
- Mod()->call_once_callback_on_jni(result);
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.blocking_future.wait_for(std::chrono::seconds(1)));
- log::info("Waiting");
-
- // Enqueue something else on the main thread and verify that it hasn't run
- static auto second_task_promise = std::promise<void>();
- auto final_future = second_task_promise.get_future();
- do_in_main_thread(common::BindOnce(
- [](std::promise<void> promise) {
- promise.set_value();
- log::info("Finally");
- },
- std::move(second_task_promise)));
- ASSERT_EQ(std::future_status::timeout, final_future.wait_for(std::chrono::milliseconds(1)));
-
- // Let the callback start
- instrumented->promises.unblock.set_value();
- ASSERT_EQ(std::future_status::ready,
- instrumented->promises.result_future.wait_for(std::chrono::seconds(1)));
- ASSERT_EQ(result, instrumented->promises.result_future.get());
-
- // Let the second task finish
- ASSERT_EQ(std::future_status::ready, final_future.wait_for(std::chrono::seconds(1)));
-}
diff --git a/system/gd/module_gdx_unittest.h b/system/gd/module_gdx_unittest.h
deleted file mode 100644
index 6765be025e..0000000000
--- a/system/gd/module_gdx_unittest.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <base/callback.h>
-#include <base/functional/bind.h>
-#include <base/location.h>
-
-#include <string>
-
-#include "common/contextual_callback.h"
-#include "module.h"
-#include "module_jniloop.h"
-#include "module_mainloop.h"
-
-using namespace bluetooth;
-
-void external_function(int /* a */, double /* b */, char /* c */);
-
-class TestGdxModule : public Module, public ModuleMainloop, public ModuleJniloop {
-public:
- void call_on_handler_protected_method(pid_t tid, int a, int b, int c);
- void call_on_main_external_function(pid_t tid, int a, double b, char c);
- void call_on_main(pid_t tid, int a, int b, int c);
- void call_on_main_repost(pid_t tid, int a, int b, int c);
- void call_on_main_recurse(pid_t tid, int a, int b, int c);
-
- void call_on_jni_external_function(pid_t tid, int a, double b, char c);
- void call_on_jni(pid_t tid, int a, int b, int c);
- void call_on_jni_repost(pid_t tid, int a, int b, int c);
- void call_on_jni_recurse(pid_t tid, int a, int b, int c);
-
- void set_callback(common::ContextualCallback<void(std::string)> one_message_callback);
- void set_once_callback(common::ContextualOnceCallback<void(std::string)> one_message_callback);
-
- void call_callback_on_handler(std::string message);
- void call_once_callback_on_handler(std::string message);
- void call_callback_on_jni(std::string message);
- void call_once_callback_on_jni(std::string message);
- void call_callback_on_main(std::string message);
- void call_once_callback_on_main(std::string message);
-
- static const bluetooth::ModuleFactory Factory;
-
-protected:
- void protected_method(int a, int b, int c);
- void call_on_main_internal(int a, int b, int c);
- void call_on_jni_internal(int a, int b, int c);
- bool IsStarted() const;
-
- void ListDependencies(bluetooth::ModuleList* /* list */) const override {}
- void Start() override;
- void Stop() override;
- std::string ToString() const override;
-
-private:
- struct PrivateImpl;
- std::shared_ptr<TestGdxModule::PrivateImpl> pimpl_;
-
- common::ContextualOnceCallback<void(std::string)> call_once_;
- common::ContextualCallback<void(std::string)> call_many_;
-
- bool started_ = false;
-
- friend bluetooth::ModuleRegistry;
-};
diff --git a/system/gd/module_jniloop.h b/system/gd/module_jniloop.h
deleted file mode 100644
index b77aa6e322..0000000000
--- a/system/gd/module_jniloop.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <base/callback.h>
-#include <base/functional/bind.h>
-#include <base/location.h>
-
-#include "btif/include/btif_jni_task.h"
-
-namespace bluetooth {
-
-class ModuleJniloop {
-protected:
- ModuleJniloop() noexcept = default;
- virtual ~ModuleJniloop() = default;
- ModuleJniloop(const ModuleJniloop& mod) = delete;
-
- // Threadsafe post onto jni loop a function with copyable arguments
- template <typename Functor, typename... Args>
- void PostFunctionOnJni(Functor&& functor, Args&&... args) const {
- do_in_jni_thread(base::BindOnce(std::forward<Functor>(functor), std::forward<Args>(args)...));
- }
-
- // Threadsafe post onto jni loop a method and context with copyable arguments
- template <typename T, typename Functor, typename... Args>
- void PostMethodOnJni(std::shared_ptr<T> ref, Functor&& functor, Args... args) const {
- do_in_jni_thread(base::BindOnce(
- [](std::weak_ptr<T> ref, Functor&& functor, Args&&... args) {
- if (std::shared_ptr<T> spt = ref.lock()) {
- base::BindOnce(std::forward<Functor>(functor), spt, std::forward<Args>(args)...)
- .Run();
- }
- },
- std::weak_ptr<T>(ref), std::forward<Functor>(functor), std::forward<Args>(args)...));
- }
-};
-
-} // namespace bluetooth
diff --git a/system/gd/module_jniloop_unittest.cc b/system/gd/module_jniloop_unittest.cc
deleted file mode 100644
index 98c6b7e09d..0000000000
--- a/system/gd/module_jniloop_unittest.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "module_jniloop_unittest.h"
-
-#include <base/callback.h>
-#include <base/functional/bind.h>
-#include <base/location.h>
-#include <base/threading/platform_thread.h>
-#include <sys/syscall.h>
-
-#include <string>
-
-#include "btif/include/btif_jni_task.h"
-#include "gtest/gtest.h"
-#include "module.h"
-#include "os/handler.h"
-#include "os/thread.h"
-
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
-using namespace bluetooth;
-
-namespace {
-constexpr int sync_timeout_in_ms = 3000;
-
-std::promise<pid_t> external_function_promise;
-std::promise<pid_t> private_impl_promise;
-std::promise<pid_t> protected_method_promise;
-
-} // namespace
-
-// Global function with C linkage
-void external_function_jni(int /* a */, double /* b */, char /* c */) {
- external_function_promise.set_value(base::PlatformThread::CurrentId());
-}
-
-// Module private implementation that is inaccessible externally
-struct TestJniModule::PrivateImpl : public ModuleJniloop {
- const int kMaxTestModuleRecurseDepth = 10;
-
- void privateCallableMethod(int /* a */, double /* b */, char /* c */) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- }
-
- void repostMethodTest(int /* a */, double /* b */, char /* c */) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- }
-
- void privateCallableRepostMethod(std::shared_ptr<TestJniModule::PrivateImpl> ptr, int a, double b,
- char c) {
- PostMethodOnJni(ptr, &PrivateImpl::repostMethodTest, a, b, c);
- }
-
- void privateCallableRecursiveMethod(std::shared_ptr<TestJniModule::PrivateImpl> ptr, int depth,
- double b, char c) {
- if (depth > kMaxTestModuleRecurseDepth) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- return;
- }
- PostMethodOnJni(ptr, &PrivateImpl::privateCallableRecursiveMethod, ptr, depth + 1, b, c);
- }
-};
-
-// Protected module method executed on handler
-void TestJniModule::call_on_handler_protected_method(int loop_tid, int a, int b, int c) {
- protected_method_promise = std::promise<pid_t>();
- auto future = protected_method_promise.get_future();
- CallOn(this, &TestJniModule::protected_method, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Global external function executed on jni loop
-void TestJniModule::call_on_jni_external_function(int loop_tid, int a, double b, char c) {
- external_function_promise = std::promise<pid_t>();
- auto future = external_function_promise.get_future();
- PostFunctionOnJni(&external_function_jni, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop
-void TestJniModule::call_on_jni(int loop_tid, int a, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnJni(pimpl_, &TestJniModule::PrivateImpl::privateCallableMethod, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on jni loop and reposted
-void TestJniModule::call_on_jni_repost(int loop_tid, int a, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnJni(pimpl_, &TestJniModule::PrivateImpl::privateCallableRepostMethod, pimpl_, a, b,
- c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on jni loop recursively
-void TestJniModule::call_on_jni_recurse(int loop_tid, int depth, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnJni(pimpl_, &TestJniModule::PrivateImpl::privateCallableRecursiveMethod, pimpl_,
- depth, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-void TestJniModule::protected_method(int /* a */, int /* b */, int /* c */) {
- protected_method_promise.set_value(base::PlatformThread::CurrentId());
-}
-
-bool TestJniModule::IsStarted() const { return pimpl_ != nullptr; }
-
-void TestJniModule::Start() {
- ASSERT_FALSE(IsStarted());
- pimpl_ = std::make_shared<TestJniModule::PrivateImpl>();
-}
-
-void TestJniModule::Stop() {
- ASSERT_TRUE(IsStarted());
- pimpl_.reset();
-}
-
-std::string TestJniModule::ToString() const { return std::string(__func__); }
-
-const bluetooth::ModuleFactory TestJniModule::Factory =
- bluetooth::ModuleFactory([]() { return new TestJniModule(); });
-
-//
-// Module GDx Testing Below
-//
-class ModuleGdxJniTest : public ::testing::Test {
-protected:
- void SetUp() override {
- test_framework_tid_ = base::PlatformThread::CurrentId();
- module_ = new TestJniModule();
- jni_thread_startup();
- jniloop_tid_ = get_jniloop_tid();
- }
-
- void TearDown() override {
- sync_jni_handler();
- jni_thread_shutdown();
- delete module_;
- }
-
- void sync_jni_handler() {
- std::promise promise = std::promise<void>();
- std::future future = promise.get_future();
- post_on_bt_jni([&promise]() { promise.set_value(); });
- future.wait_for(std::chrono::milliseconds(sync_timeout_in_ms));
- }
-
- static pid_t get_jniloop_tid() {
- std::promise<pid_t> pid_promise = std::promise<pid_t>();
- auto future = pid_promise.get_future();
- post_on_bt_jni([&pid_promise]() { pid_promise.set_value(base::PlatformThread::CurrentId()); });
- return future.get();
- }
-
- pid_t test_framework_tid_{-1};
- pid_t jniloop_tid_{-1};
- TestModuleRegistry module_registry_;
- TestJniModule* module_;
-};
-
-class ModuleGdxWithJniStackTest : public ModuleGdxJniTest {
-protected:
- void SetUp() override {
- ModuleGdxJniTest::SetUp();
- module_registry_.InjectTestModule(&TestJniModule::Factory, module_ /* pass ownership */);
- module_ = nullptr; // ownership is passed
- handler_tid_ = get_handler_tid(module_registry_.GetTestModuleHandler(&TestJniModule::Factory));
- }
-
- static pid_t get_handler_tid(os::Handler* handler) {
- std::promise<pid_t> handler_tid_promise = std::promise<pid_t>();
- std::future<pid_t> future = handler_tid_promise.get_future();
- handler->Post(common::BindOnce(
- [](std::promise<pid_t> promise) {
- promise.set_value(base::PlatformThread::CurrentId());
- },
- std::move(handler_tid_promise)));
- return future.get();
- }
-
- void TearDown() override {
- module_registry_.StopAll();
- ModuleGdxJniTest::TearDown();
- }
-
- TestJniModule* Mod() { return module_registry_.GetModuleUnderTest<TestJniModule>(); }
-
- pid_t handler_tid_{-1};
-};
-
-TEST_F(ModuleGdxJniTest, nop) {}
-
-TEST_F(ModuleGdxJniTest, lifecycle) {
- ::bluetooth::os::Thread* thread =
- new bluetooth::os::Thread("Name", bluetooth::os::Thread::Priority::REAL_TIME);
- ASSERT_FALSE(module_registry_.IsStarted<TestJniModule>());
- module_registry_.Start<TestJniModule>(thread);
- ASSERT_TRUE(module_registry_.IsStarted<TestJniModule>());
- module_registry_.StopAll();
- ASSERT_FALSE(module_registry_.IsStarted<TestJniModule>());
- delete thread;
-}
-
-TEST_F(ModuleGdxWithJniStackTest, call_on_handler_protected_method) {
- Mod()->call_on_handler_protected_method(handler_tid_, 1, 2, 3);
-}
-
-TEST_F(ModuleGdxWithJniStackTest, test_call_on_jni) { Mod()->call_on_jni(jniloop_tid_, 1, 2, 3); }
-
-TEST_F(ModuleGdxWithJniStackTest, test_call_external_function) {
- Mod()->call_on_jni_external_function(jniloop_tid_, 1, 2.3, 'c');
-}
-
-TEST_F(ModuleGdxWithJniStackTest, test_call_on_jni_repost) {
- Mod()->call_on_jni_repost(jniloop_tid_, 1, 2, 3);
-}
-
-TEST_F(ModuleGdxWithJniStackTest, test_call_on_jni_recurse) {
- Mod()->call_on_jni_recurse(jniloop_tid_, 1, 2, 3);
-}
diff --git a/system/gd/module_jniloop_unittest.h b/system/gd/module_jniloop_unittest.h
deleted file mode 100644
index 032606251e..0000000000
--- a/system/gd/module_jniloop_unittest.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <base/callback.h>
-#include <base/functional/bind.h>
-#include <base/location.h>
-
-#include <string>
-
-#include "module.h"
-#include "module_jniloop.h"
-
-using namespace bluetooth;
-
-void external_function(int /* a */, double /* b */, char /* c */);
-
-class TestJniModule : public Module, public ModuleJniloop {
-public:
- void call_on_handler_protected_method(pid_t tid, int a, int b, int c);
- void call_on_jni_external_function(pid_t tid, int a, double b, char c);
- void call_on_jni(pid_t tid, int a, int b, int c);
- void call_on_jni_repost(pid_t tid, int a, int b, int c);
- void call_on_jni_recurse(pid_t tid, int a, int b, int c);
-
- static const bluetooth::ModuleFactory Factory;
-
-protected:
- void protected_method(int a, int b, int c);
- void call_on_jni_internal(int a, int b, int c);
- bool IsStarted() const;
-
- void ListDependencies(bluetooth::ModuleList* /* list */) const override {}
- void Start() override;
- void Stop() override;
- std::string ToString() const override;
-
-private:
- struct PrivateImpl;
- std::shared_ptr<TestJniModule::PrivateImpl> pimpl_;
-
- bool started_ = false;
-
- friend bluetooth::ModuleRegistry;
-};
diff --git a/system/gd/module_mainloop.h b/system/gd/module_mainloop.h
deleted file mode 100644
index 9f07e89ef6..0000000000
--- a/system/gd/module_mainloop.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <base/callback.h>
-#include <base/functional/bind.h>
-#include <base/location.h>
-
-#include "stack/include/main_thread.h"
-
-namespace bluetooth {
-
-class ModuleMainloop {
-protected:
- ModuleMainloop() noexcept = default;
- virtual ~ModuleMainloop() = default;
- ModuleMainloop(const ModuleMainloop& mod) = delete;
-
- // Threadsafe post onto mainloop a function with copyable arguments
- template <typename Functor, typename... Args>
- void PostFunctionOnMain(Functor&& functor, Args&&... args) const {
- do_in_main_thread(base::BindOnce(std::forward<Functor>(functor), std::forward<Args>(args)...));
- }
-
- // Threadsafe post onto mainloop a method and context with copyable arguments
- template <typename T, typename Functor, typename... Args>
- void PostMethodOnMain(std::shared_ptr<T> ref, Functor&& functor, Args... args) const {
- do_in_main_thread(base::BindOnce(
- [](std::weak_ptr<T> ref, Functor&& functor, Args&&... args) {
- if (std::shared_ptr<T> spt = ref.lock()) {
- base::BindOnce(std::forward<Functor>(functor), spt, std::forward<Args>(args)...)
- .Run();
- }
- },
- std::weak_ptr<T>(ref), std::forward<Functor>(functor), std::forward<Args>(args)...));
- }
-};
-
-} // namespace bluetooth
diff --git a/system/gd/module_mainloop_unittest.cc b/system/gd/module_mainloop_unittest.cc
deleted file mode 100644
index cac37f83fe..0000000000
--- a/system/gd/module_mainloop_unittest.cc
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "module_mainloop_unittest.h"
-
-#include <base/callback.h>
-#include <base/functional/bind.h>
-#include <base/location.h>
-#include <base/threading/platform_thread.h>
-#include <sys/syscall.h>
-
-#include <string>
-
-#include "gtest/gtest.h"
-#include "module.h"
-#include "os/handler.h"
-#include "os/thread.h"
-#include "stack/include/main_thread.h"
-
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
-using namespace bluetooth;
-
-namespace {
-constexpr int sync_timeout_in_ms = 3000;
-
-std::promise<pid_t> external_function_promise;
-std::promise<pid_t> private_impl_promise;
-std::promise<pid_t> protected_method_promise;
-
-} // namespace
-
-// Global function with C linkage
-void external_function_main(int /* a */, double /* b */, char /* c */) {
- external_function_promise.set_value(base::PlatformThread::CurrentId());
-}
-
-// Module private implementation that is inaccessible externally
-struct TestModule::PrivateImpl : public ModuleMainloop {
- const int kMaxTestModuleRecurseDepth = 10;
-
- void privateCallableMethod(int /* a */, double /* b */, char /* c */) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- }
-
- void repostMethodTest(int /* a */, double /* b */, char /* c */) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- }
-
- void privateCallableRepostMethod(std::shared_ptr<TestModule::PrivateImpl> ptr, int a, double b,
- char c) {
- PostMethodOnMain(ptr, &PrivateImpl::repostMethodTest, a, b, c);
- }
-
- void privateCallableRecursiveMethod(std::shared_ptr<TestModule::PrivateImpl> ptr, int depth,
- double b, char c) {
- if (depth > kMaxTestModuleRecurseDepth) {
- private_impl_promise.set_value(base::PlatformThread::CurrentId());
- return;
- }
- PostMethodOnMain(ptr, &PrivateImpl::privateCallableRecursiveMethod, ptr, depth + 1, b, c);
- }
-};
-
-// Protected module method executed on handler
-void TestModule::call_on_handler_protected_method(int loop_tid, int a, int b, int c) {
- protected_method_promise = std::promise<pid_t>();
- auto future = protected_method_promise.get_future();
- CallOn(this, &TestModule::protected_method, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Global external function executed on main loop
-void TestModule::call_on_main_external_function(int loop_tid, int a, double b, char c) {
- external_function_promise = std::promise<pid_t>();
- auto future = external_function_promise.get_future();
- PostFunctionOnMain(&external_function_main, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop
-void TestModule::call_on_main(int loop_tid, int a, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnMain(pimpl_, &TestModule::PrivateImpl::privateCallableMethod, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop and reposted
-void TestModule::call_on_main_repost(int loop_tid, int a, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnMain(pimpl_, &TestModule::PrivateImpl::privateCallableRepostMethod, pimpl_, a, b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-// Private implementation method executed on main loop recursively
-void TestModule::call_on_main_recurse(int loop_tid, int depth, int b, int c) {
- private_impl_promise = std::promise<pid_t>();
- auto future = private_impl_promise.get_future();
- PostMethodOnMain(pimpl_, &TestModule::PrivateImpl::privateCallableRecursiveMethod, pimpl_, depth,
- b, c);
- ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready);
- ASSERT_EQ(future.get(), loop_tid);
-}
-
-void TestModule::protected_method(int /* a */, int /* b */, int /* c */) {
- protected_method_promise.set_value(base::PlatformThread::CurrentId());
-}
-
-bool TestModule::IsStarted() const { return pimpl_ != nullptr; }
-
-void TestModule::Start() {
- ASSERT_FALSE(IsStarted());
- pimpl_ = std::make_shared<TestModule::PrivateImpl>();
-}
-
-void TestModule::Stop() {
- ASSERT_TRUE(IsStarted());
- pimpl_.reset();
-}
-
-std::string TestModule::ToString() const { return std::string(__func__); }
-
-const bluetooth::ModuleFactory TestModule::Factory =
- bluetooth::ModuleFactory([]() { return new TestModule(); });
-
-//
-// Module GDx Testing Below
-//
-class ModuleMainGdxTest : public ::testing::Test {
-protected:
- void SetUp() override {
- test_framework_tid_ = base::PlatformThread::CurrentId();
- module_ = new TestModule();
- main_thread_start_up();
- mainloop_tid_ = get_mainloop_tid();
- }
-
- void TearDown() override {
- sync_main_handler();
- main_thread_shut_down();
- delete module_;
- }
-
- void sync_main_handler() {
- std::promise promise = std::promise<void>();
- std::future future = promise.get_future();
- post_on_bt_main([&promise]() { promise.set_value(); });
- future.wait_for(std::chrono::milliseconds(sync_timeout_in_ms));
- }
-
- static pid_t get_mainloop_tid() {
- std::promise<pid_t> pid_promise = std::promise<pid_t>();
- auto future = pid_promise.get_future();
- post_on_bt_main([&pid_promise]() { pid_promise.set_value(base::PlatformThread::CurrentId()); });
- return future.get();
- }
-
- pid_t test_framework_tid_{-1};
- pid_t mainloop_tid_{-1};
- TestModuleRegistry module_registry_;
- TestModule* module_;
-};
-
-class ModuleMainGdxWithStackTest : public ModuleMainGdxTest {
-protected:
- void SetUp() override {
- ModuleMainGdxTest::SetUp();
- module_registry_.InjectTestModule(&TestModule::Factory, module_ /* pass ownership */);
- module_ = nullptr; // ownership is passed
- handler_tid_ = get_handler_tid(module_registry_.GetTestModuleHandler(&TestModule::Factory));
- }
-
- static pid_t get_handler_tid(os::Handler* handler) {
- std::promise<pid_t> handler_tid_promise = std::promise<pid_t>();
- std::future<pid_t> future = handler_tid_promise.get_future();
- handler->Post(common::BindOnce(
- [](std::promise<pid_t> promise) {
- promise.set_value(base::PlatformThread::CurrentId());
- },
- std::move(handler_tid_promise)));
- return future.get();
- }
-
- void TearDown() override {
- module_registry_.StopAll();
- ModuleMainGdxTest::TearDown();
- }
-
- TestModule* Mod() { return module_registry_.GetModuleUnderTest<TestModule>(); }
-
- pid_t handler_tid_{-1};
-};
-
-TEST_F(ModuleMainGdxTest, nop) {}
-
-TEST_F(ModuleMainGdxTest, lifecycle) {
- ::bluetooth::os::Thread* thread =
- new bluetooth::os::Thread("Name", bluetooth::os::Thread::Priority::REAL_TIME);
- ASSERT_FALSE(module_registry_.IsStarted<TestModule>());
- module_registry_.Start<TestModule>(thread);
- ASSERT_TRUE(module_registry_.IsStarted<TestModule>());
- module_registry_.StopAll();
- ASSERT_FALSE(module_registry_.IsStarted<TestModule>());
- delete thread;
-}
-
-TEST_F(ModuleMainGdxWithStackTest, call_on_handler_protected_method) {
- Mod()->call_on_handler_protected_method(handler_tid_, 1, 2, 3);
-}
-
-TEST_F(ModuleMainGdxWithStackTest, test_call_on_main) {
- Mod()->call_on_main(mainloop_tid_, 1, 2, 3);
-}
-
-TEST_F(ModuleMainGdxWithStackTest, test_call_external_function) {
- Mod()->call_on_main_external_function(mainloop_tid_, 1, 2.3, 'c');
-}
-
-TEST_F(ModuleMainGdxWithStackTest, test_call_on_main_repost) {
- Mod()->call_on_main_repost(mainloop_tid_, 1, 2, 3);
-}
-
-TEST_F(ModuleMainGdxWithStackTest, test_call_on_main_recurse) {
- Mod()->call_on_main_recurse(mainloop_tid_, 1, 2, 3);
-}
diff --git a/system/gd/module_mainloop_unittest.h b/system/gd/module_mainloop_unittest.h
deleted file mode 100644
index 8e864f33d7..0000000000
--- a/system/gd/module_mainloop_unittest.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <base/callback.h>
-#include <base/functional/bind.h>
-#include <base/location.h>
-
-#include <string>
-
-#include "module.h"
-#include "module_mainloop.h"
-
-using namespace bluetooth;
-
-void external_function(int /* a */, double /* b */, char /* c */);
-
-class TestModule : public Module, public ModuleMainloop {
-public:
- void call_on_handler_protected_method(pid_t tid, int a, int b, int c);
- void call_on_main_external_function(pid_t tid, int a, double b, char c);
- void call_on_main(pid_t tid, int a, int b, int c);
- void call_on_main_repost(pid_t tid, int a, int b, int c);
- void call_on_main_recurse(pid_t tid, int a, int b, int c);
-
- static const bluetooth::ModuleFactory Factory;
-
-protected:
- void protected_method(int a, int b, int c);
- void call_on_main_internal(int a, int b, int c);
- bool IsStarted() const;
-
- void ListDependencies(bluetooth::ModuleList* /* list */) const override {}
- void Start() override;
- void Stop() override;
- std::string ToString() const override;
-
-private:
- struct PrivateImpl;
- std::shared_ptr<TestModule::PrivateImpl> pimpl_;
-
- bool started_ = false;
-
- friend bluetooth::ModuleRegistry;
-};
diff --git a/system/gd/module_state_dumper_unittest.cc b/system/gd/module_state_dumper_unittest.cc
deleted file mode 100644
index 2bb3e92add..0000000000
--- a/system/gd/module_state_dumper_unittest.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "module_state_dumper_unittest.h"
-
-#include <base/callback.h>
-#include <base/functional/bind.h>
-#include <base/location.h>
-#include <base/threading/platform_thread.h>
-#include <bluetooth/log.h>
-#include <sys/syscall.h>
-
-#include <sstream>
-#include <string>
-
-#include "gtest/gtest.h"
-#include "module_dumper.h"
-#include "os/handler.h"
-#include "os/thread.h"
-#include "stack/include/main_thread.h"
-
-using namespace bluetooth;
-
-namespace {
-
-constexpr int sync_timeout_in_ms = 3000;
-constexpr char title[] = "module_state_dumper_test";
-
-} // namespace
-
-// Module private implementation that is inaccessible externally
-struct StateDumperTestModule::PrivateImpl : public ModuleMainloop {};
-
-bool StateDumperTestModule::IsStarted() const { return pimpl_ != nullptr; }
-
-void StateDumperTestModule::Start() {
- ASSERT_FALSE(IsStarted());
- pimpl_ = std::make_shared<StateDumperTestModule::PrivateImpl>();
-}
-
-void StateDumperTestModule::Stop() {
- ASSERT_TRUE(IsStarted());
- pimpl_.reset();
-}
-
-std::string StateDumperTestModule::ToString() const { return std::string(__func__); }
-
-const bluetooth::ModuleFactory StateDumperTestModule::Factory =
- bluetooth::ModuleFactory([]() { return new StateDumperTestModule(); });
-
-DumpsysDataFinisher StateDumperTestModule::GetDumpsysData(
- flatbuffers::FlatBufferBuilder* /* builder */) const {
- log::info("flatbuffers");
- return EmptyDumpsysDataFinisher;
-}
-
-//
-// Module GDx Testing Below
-//
-class ModuleStateDumperTest : public ::testing::Test {
-protected:
- void SetUp() override {
- test_framework_tid_ = base::PlatformThread::CurrentId();
- module_ = new StateDumperTestModule();
- main_thread_start_up();
- mainloop_tid_ = get_mainloop_tid();
- }
-
- void TearDown() override {
- sync_main_handler();
- main_thread_shut_down();
- delete module_;
- }
-
- void sync_main_handler() {
- std::promise promise = std::promise<void>();
- std::future future = promise.get_future();
- post_on_bt_main([&promise]() { promise.set_value(); });
- future.wait_for(std::chrono::milliseconds(sync_timeout_in_ms));
- }
-
- static pid_t get_mainloop_tid() {
- std::promise<pid_t> pid_promise = std::promise<pid_t>();
- auto future = pid_promise.get_future();
- post_on_bt_main([&pid_promise]() { pid_promise.set_value(base::PlatformThread::CurrentId()); });
- return future.get();
- }
-
- pid_t test_framework_tid_{-1};
- pid_t mainloop_tid_{-1};
- TestModuleRegistry module_registry_;
- StateDumperTestModule* module_;
-};
-
-class ModuleStateDumperWithStackTest : public ModuleStateDumperTest {
-protected:
- void SetUp() override {
- ModuleStateDumperTest::SetUp();
- module_registry_.InjectTestModule(&StateDumperTestModule::Factory,
- module_ /* pass ownership */);
- module_ = nullptr; // ownership is passed
- }
-
- static pid_t get_handler_tid(os::Handler* handler) {
- std::promise<pid_t> handler_tid_promise = std::promise<pid_t>();
- std::future<pid_t> future = handler_tid_promise.get_future();
- handler->Post(common::BindOnce(
- [](std::promise<pid_t> promise) {
- promise.set_value(base::PlatformThread::CurrentId());
- },
- std::move(handler_tid_promise)));
- return future.get();
- }
-
- void TearDown() override {
- module_registry_.StopAll();
- ModuleStateDumperTest::TearDown();
- }
-
- StateDumperTestModule* Mod() {
- return module_registry_.GetModuleUnderTest<StateDumperTestModule>();
- }
-
- pid_t handler_tid_{-1};
-};
-
-TEST_F(ModuleStateDumperTest, lifecycle) {
- ::bluetooth::os::Thread* thread =
- new bluetooth::os::Thread("Name", bluetooth::os::Thread::Priority::REAL_TIME);
- ASSERT_FALSE(module_registry_.IsStarted<StateDumperTestModule>());
- module_registry_.Start<StateDumperTestModule>(thread);
- ASSERT_TRUE(module_registry_.IsStarted<StateDumperTestModule>());
- module_registry_.StopAll();
- ASSERT_FALSE(module_registry_.IsStarted<StateDumperTestModule>());
- delete thread;
-}
-
-TEST_F(ModuleStateDumperWithStackTest, dump_state) {
- ModuleDumper dumper(STDOUT_FILENO, module_registry_, title);
-
- std::string output;
- std::ostringstream oss;
- dumper.DumpState(&output, oss);
-
- log::info("DUMP STATE");
- log::info("{}", oss.str());
- log::info("{}", output);
-}
diff --git a/system/gd/module_state_dumper_unittest.h b/system/gd/module_state_dumper_unittest.h
deleted file mode 100644
index 7c2a1e6f1c..0000000000
--- a/system/gd/module_state_dumper_unittest.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <memory>
-#include <string>
-
-#include "module.h"
-#include "module_mainloop.h"
-
-using namespace bluetooth;
-
-class StateDumperTestModule : public Module, public ModuleMainloop {
-public:
- static const bluetooth::ModuleFactory Factory;
-
-protected:
- bool IsStarted() const;
-
- void ListDependencies(bluetooth::ModuleList* /* list */) const override {}
- void Start() override;
- void Stop() override;
- std::string ToString() const override;
-
- DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const override;
-
-private:
- struct PrivateImpl;
- std::shared_ptr<StateDumperTestModule::PrivateImpl> pimpl_;
-
- bool started_ = false;
-
- friend bluetooth::ModuleRegistry;
-};
diff --git a/system/gd/rust/topshim/facade/Android.bp b/system/gd/rust/topshim/facade/Android.bp
index cfecd4465b..725ddaa355 100644
--- a/system/gd/rust/topshim/facade/Android.bp
+++ b/system/gd/rust/topshim/facade/Android.bp
@@ -38,7 +38,6 @@ rust_defaults {
"lib-bt-packets-base",
"libFraunhoferAAC",
"libbluetooth-dumpsys",
- "libbluetooth-gdx",
"libbluetooth-types",
"libbluetooth_crypto_toolbox",
"libbluetooth_gd", // Gabeldorsche
diff --git a/system/main/Android.bp b/system/main/Android.bp
index 454dd79400..cfa85eea7e 100644
--- a/system/main/Android.bp
+++ b/system/main/Android.bp
@@ -192,14 +192,12 @@ cc_test {
"shim/utils.cc",
"test/common_stack_test.cc",
"test/main_shim_dumpsys_test.cc",
- "test/main_shim_stack_lifecycle_test.cc",
"test/main_shim_test.cc",
],
static_libs: [
"bluetooth_flags_c_lib_for_test",
"libbase",
"libbluetooth-dumpsys",
- "libbluetooth-gdx",
"libbluetooth-types",
"libbluetooth_core_rs_bridge",
"libbluetooth_crypto_toolbox",
@@ -241,105 +239,3 @@ cc_test {
min_sdk_version: "Tiramisu",
header_libs: ["libbluetooth_headers"],
}
-
-cc_test {
- name: "net_test_main_dumpsys",
- test_suites: ["general-tests"],
- host_supported: true,
- test_options: {
- unit_test: true,
- },
- defaults: [
- "fluoride_defaults",
- "mts_defaults",
- ],
- include_dirs: [
- "packages/modules/Bluetooth/system",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/stack/btm",
- "packages/modules/Bluetooth/system/stack/include",
- ],
- generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
- "BluetoothGeneratedDumpsysDataSchema_h",
- ],
- srcs: [
- ":BluetoothOsSources_host",
- ":BluetoothStackManagerSources",
- ":LibBluetoothShimSources",
- ":TestCommonMainHandler",
- ":TestCommonMockFunctions",
- ":TestMockBta",
- ":TestMockBtif",
- ":TestMockBtu",
- ":TestMockJni",
- ":TestMockLegacyHciCommands",
- ":TestMockLegacyHciInterface",
- ":TestMockStack",
- ":TestMockStackRnr",
- "test/main_shim_stack_dumpsys_test.cc",
- ],
- static_libs: [
- "bluetooth_flags_c_lib_for_test",
- "libbase",
- "libbluetooth-dumpsys",
- "libbluetooth-gdx",
- "libbluetooth-types",
- "libbluetooth_core_rs_bridge",
- "libbluetooth_crypto_toolbox",
- "libbluetooth_gd",
- "libbluetooth_hci_pdl",
- "libbluetooth_log",
- "libbt-common",
- "libbt-platform-protos-lite",
- "libbtdevice",
- "libchrome",
- "libcom.android.sysprop.bluetooth.wrapped",
- "libevent",
- "libflatbuffers-cpp",
- "libgmock",
- "liblog",
- "libosi",
- ],
- shared_libs: [
- "libPlatformProperties",
- "libaconfig_storage_read_api_cc",
- "libcrypto",
- "server_configurable_flags",
- ],
- target: {
- linux: {
- srcs: [
- ":BluetoothOsSources_fake_timer",
- ],
- },
- android: {
- static_libs: [
- "android.hardware.bluetooth@1.0",
- "android.hardware.bluetooth@1.1",
- "android.system.suspend-V1-ndk",
- "android.system.suspend.control-V1-ndk",
- "libstatslog_bt",
- ],
- shared_libs: [
- "libbinder_ndk",
- "libcutils",
- "libhidlbase",
- "libstatssocket",
- "libutils",
- ],
- },
- },
- sanitize: {
- address: true,
- all_undefined: true,
- cfi: true,
- integer_overflow: true,
- scs: true,
- diag: {
- undefined: true,
- },
- },
- min_sdk_version: "Tiramisu",
- header_libs: ["libbluetooth_headers"],
-}
diff --git a/system/main/test/main_shim_stack_dumpsys_test.cc b/system/main/test/main_shim_stack_dumpsys_test.cc
deleted file mode 100644
index 30e6df1225..0000000000
--- a/system/main/test/main_shim_stack_dumpsys_test.cc
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <bluetooth/log.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-
-#include <cstdlib>
-#include <memory>
-
-#include "common/circular_buffer.h"
-#include "common/strings.h"
-#include "gd/module_jniloop.h"
-#include "gd/module_mainloop.h"
-#include "hci/include/packet_fragmenter.h"
-#include "main/shim/dumpsys.h"
-#include "main/shim/entry.h"
-#include "main/shim/stack.h"
-#include "module.h"
-#include "os/thread.h"
-#include "shim/dumpsys.h"
-#include "stack/btm/btm_int_types.h"
-#include "stack/btm/btm_sec_cb.h"
-#include "stack/include/main_thread.h"
-#include "test/mock/mock_main_shim_entry.h"
-
-using ::testing::_;
-
-using namespace bluetooth;
-using namespace testing;
-
-tBTM_CB btm_cb{}; // main::shim::le_scanning_manager
-tBTM_SEC_CB btm_sec_cb{}; // main::shim::acl
-
-const packet_fragmenter_t* packet_fragmenter_get_interface() {
- return nullptr;
-} // main::shim::hci_layer
-bluetooth::common::TimestamperInMilliseconds
- timestamper_in_milliseconds; // main::shim::le_scanning_manager
-
-namespace {
-constexpr char kLogTagStopped[] = "STOPPED";
-constexpr char kLogTagStarting[] = "STARTING";
-constexpr char kLogTagStarted[] = "STARTED";
-constexpr char kLogTagQuiescing[] = "QUIESCING";
-constexpr char kLogTagQuiesced[] = "QUIESCED";
-
-constexpr char kTestStackThreadName[] = "test_stack_thread";
-constexpr int kSyncMainLoopTimeoutMs = 3000;
-constexpr int kWaitUntilHandlerStoppedMs = 2000;
-constexpr size_t kNumTestClients = 10;
-
-constexpr size_t kTagLength = 48 + sizeof(' ') + sizeof(' ');
-inline void log_tag(std::string tag) {
- std::string prepend(kTagLength / 2 - tag.size() / 2, '=');
- std::string append(kTagLength / 2 - tag.size() / 2, '=');
- log::info("{} {} {}", prepend, tag, append);
-}
-
-class MainThread {
-public:
- MainThread() {
- main_thread_start_up();
- post_on_bt_main([]() { log::info("<=== tid Main loop started"); });
- }
-
- ~MainThread() {
- sync_main_handler();
- main_thread_shut_down();
- }
-
-private:
- void sync_main_handler() {
- std::promise promise = std::promise<void>();
- std::future future = promise.get_future();
- post_on_bt_main([&promise]() { promise.set_value(); });
- future.wait_for(std::chrono::milliseconds(kSyncMainLoopTimeoutMs));
- }
-};
-
-class TestStackManager {
-public:
- TestStackManager() {
- // Stack manager is started in the test after each test uses the default
- // or adds their own modules
- }
-
- ~TestStackManager() {
- log::debug("Deleting stack manager");
- Stop();
- }
-
- TestStackManager(const TestStackManager&) = delete;
-
- template <typename T>
- void AddModule() {
- modules_.add<T>();
- }
-
- void Start() {
- if (stack_started_) {
- return;
- }
- log::info("Starting up stack manager");
- stack_started_ = true;
- bluetooth::os::Thread* stack_thread = new bluetooth::os::Thread(
- kTestStackThreadName, bluetooth::os::Thread::Priority::NORMAL);
- bluetooth::shim::Stack::GetInstance()->StartModuleStack(&modules_, stack_thread);
- bluetooth::shim::Stack::GetInstance()->GetHandler()->Call(
- []() { log::info("<=== tid GD Event loop started"); });
- }
-
- void Stop() {
- if (!stack_started_) {
- return;
- }
- stack_started_ = false;
- bluetooth::shim::Stack::GetInstance()->Stop();
- }
-
- // NOTE: Stack manager *must* be active else method returns nullptr
- // if stack manager has not started or shutdown
- template <typename T>
- static T* GetUnsafeModule() {
- return bluetooth::shim::Stack::GetInstance()->GetStackManager()->GetInstance<T>();
- }
-
- size_t NumModules() const { return modules_.NumModules(); }
-
-private:
- bluetooth::ModuleList modules_;
- bool stack_started_{false};
-};
-
-// Data returned via callback from a stack managed module
-struct TestCallbackData {
- int iter;
- std::string tag;
-};
-
-// Data sent to a stack managed module via a module API
-struct TestData {
- int iter;
- std::string tag;
- std::function<void(TestCallbackData callback_data)> callback;
-};
-
-} // namespace
-
-class TestStackDumpsysBase : public bluetooth::Module, public ModuleMainloop, public ModuleJniloop {
-public:
- TestStackDumpsysBase(const TestStackDumpsysBase&) = delete;
- TestStackDumpsysBase& operator=(const TestStackDumpsysBase&) = delete;
-
- virtual ~TestStackDumpsysBase() {}
- static const ModuleFactory Factory;
-
- virtual void TestMethod(TestData test_data) const {
- log::info("Test base class iter:{} tag:{}", test_data.iter, test_data.tag);
- }
-
-protected:
- void ListDependencies(ModuleList* /* list */) const override {}
- void Start() override { log::error("Started TestStackDumpsysBase"); }
- void Stop() override { log::error("Stopped TestStackDumpsysBase"); }
- std::string ToString() const override { return std::string("TestFunction"); }
-
- TestStackDumpsysBase() = default;
-};
-
-struct StackRunningData {
- std::function<void(bool is_running)> cb;
-};
-
-class TestStackDumpsys1 : public TestStackDumpsysBase {
-public:
- TestStackDumpsys1(const TestStackDumpsys1&) = delete;
- TestStackDumpsys1& operator=(const TestStackDumpsys1&) = delete;
- virtual ~TestStackDumpsys1() = default;
-
- static const ModuleFactory Factory;
-
- void TestMethod(TestData test_data) const override;
- void IsStackRunning(StackRunningData stack_running_data) const;
-
-private:
- struct impl;
- std::shared_ptr<impl> impl_;
- TestStackDumpsys1();
-};
-
-struct TestStackDumpsys1::impl : public ModuleMainloop, public ModuleJniloop {
- void test(TestData test_data) {
- TestCallbackData callback_data{
- .iter = test_data.iter,
- .tag = std::string(__func__),
- };
- PostFunctionOnMain([](std::function<void(TestCallbackData callback_data)> callback,
- TestCallbackData data) { callback(data); },
- test_data.callback, callback_data);
- }
- void is_stack_running(StackRunningData stack_running_data) const {
- bool is_running = bluetooth::shim::Stack::GetInstance()->IsRunning();
- if (stack_running_data.cb) {
- stack_running_data.cb(is_running);
- }
- }
-};
-
-TestStackDumpsys1::TestStackDumpsys1() : TestStackDumpsysBase() {
- impl_ = std::make_shared<impl>();
-}
-
-void TestStackDumpsys1::TestMethod(TestData test_data) const {
- PostMethodOnMain(impl_, &impl::test, test_data);
-}
-
-void TestStackDumpsys1::IsStackRunning(StackRunningData stack_running_data) const {
- GetHandler()->CallOn(impl_.get(), &impl::is_stack_running, stack_running_data);
-}
-
-class TestStackDumpsys2 : public TestStackDumpsysBase {
-public:
- TestStackDumpsys2(const TestStackDumpsys2&) = delete;
- TestStackDumpsys2& operator=(const TestStackDumpsys2&) = delete;
- virtual ~TestStackDumpsys2() = default;
-
- static const ModuleFactory Factory;
-
- void TestMethod(TestData test_data) const override;
-
-private:
- struct impl;
- std::shared_ptr<impl> impl_;
- TestStackDumpsys2();
-};
-
-struct TestStackDumpsys2::impl : public ModuleMainloop, public ModuleJniloop {
- void test(TestData test_data) {
- TestCallbackData callback_data{
- .iter = test_data.iter,
- .tag = std::string(__func__),
- };
- PostFunctionOnMain([](std::function<void(TestCallbackData callback_data)> callback,
- TestCallbackData data) { callback(data); },
- test_data.callback, callback_data);
- }
-};
-
-TestStackDumpsys2::TestStackDumpsys2() : TestStackDumpsysBase() {
- impl_ = std::make_shared<impl>();
-}
-
-void TestStackDumpsys2::TestMethod(TestData test_data) const {
- PostMethodOnMain(impl_, &impl::test, test_data);
-}
-
-class TestStackDumpsys3 : public TestStackDumpsysBase {
-public:
- TestStackDumpsys3(const TestStackDumpsys3&) = delete;
- TestStackDumpsys3& operator=(const TestStackDumpsys3&) = delete;
- virtual ~TestStackDumpsys3() = default;
-
- static const ModuleFactory Factory;
-
- void TestMethod(TestData test_data) const override;
-
-private:
- struct impl;
- std::shared_ptr<impl> impl_;
- TestStackDumpsys3();
-};
-
-struct TestStackDumpsys3::impl : public ModuleMainloop, public ModuleJniloop {
- void test(TestData test_data) {
- TestCallbackData callback_data{
- .iter = test_data.iter,
- .tag = std::string(__func__),
- };
- PostFunctionOnMain([](std::function<void(TestCallbackData callback_data)> callback,
- TestCallbackData data) { callback(data); },
- test_data.callback, callback_data);
- }
-};
-
-TestStackDumpsys3::TestStackDumpsys3() : TestStackDumpsysBase() {
- impl_ = std::make_shared<impl>();
-}
-
-void TestStackDumpsys3::TestMethod(TestData test_data) const {
- PostMethodOnMain(impl_, &impl::test, test_data);
-}
-
-class TestStackDumpsys4 : public TestStackDumpsysBase {
-public:
- TestStackDumpsys4(const TestStackDumpsys4&) = delete;
- TestStackDumpsys4& operator=(const TestStackDumpsys3&) = delete;
- virtual ~TestStackDumpsys4() = default;
-
- static const ModuleFactory Factory;
-
- void TestMethod(TestData test_data) const override {
- log::info("mod:{} iter:{} tag:{}", __func__, test_data.iter, test_data.tag);
- }
-
-private:
- struct impl;
- std::shared_ptr<impl> impl_;
- TestStackDumpsys4() : TestStackDumpsysBase() {}
-};
-
-struct TestStackDumpsys4::impl : public ModuleMainloop, public ModuleJniloop {};
-
-const ModuleFactory TestStackDumpsysBase::Factory =
- ModuleFactory([]() { return new TestStackDumpsysBase(); });
-
-const ModuleFactory TestStackDumpsys1::Factory =
- ModuleFactory([]() { return new TestStackDumpsys1(); });
-const ModuleFactory TestStackDumpsys2::Factory =
- ModuleFactory([]() { return new TestStackDumpsys2(); });
-const ModuleFactory TestStackDumpsys3::Factory =
- ModuleFactory([]() { return new TestStackDumpsys3(); });
-const ModuleFactory TestStackDumpsys4::Factory =
- ModuleFactory([]() { return new TestStackDumpsys4(); });
-
-class StackWithMainThreadUnitTest : public ::testing::Test {
-protected:
- void SetUp() override { main_thread_ = std::make_unique<MainThread>(); }
- void TearDown() override { main_thread_.reset(); }
-
-private:
- std::unique_ptr<MainThread> main_thread_;
-};
-
-class StackLifecycleUnitTest : public StackWithMainThreadUnitTest {
-public:
- std::shared_ptr<TestStackManager> StackManager() const { return stack_manager_; }
-
-protected:
- void SetUp() override {
- StackWithMainThreadUnitTest::SetUp();
- stack_manager_ = std::make_shared<TestStackManager>();
- }
-
- void TearDown() override {
- stack_manager_.reset();
- StackWithMainThreadUnitTest::TearDown();
- }
-
-private:
- std::shared_ptr<TestStackManager> stack_manager_;
-};
-
-class MainShimStackDumpsysTest : public StackLifecycleUnitTest {
-protected:
- void SetUp() override {
- StackLifecycleUnitTest::SetUp();
- StackManager()->AddModule<TestStackDumpsys1>();
- StackManager()->AddModule<TestStackDumpsys2>();
- StackManager()->AddModule<TestStackDumpsys3>();
- StackManager()->AddModule<bluetooth::shim::Dumpsys>();
- StackManager()->Start();
- ASSERT_EQ(4U, StackManager()->NumModules());
-
- bluetooth::shim::RegisterDumpsysFunction(
- (void*)this, [](int fd) { log::info("Callback to dump legacy data fd:{}", fd); });
- }
-
- void TearDown() override {
- bluetooth::shim::UnregisterDumpsysFunction((void*)this);
- StackLifecycleUnitTest::TearDown();
- }
-};
-
-struct CallablePostCnt {
- size_t success{0};
- size_t misses{0};
- CallablePostCnt operator+=(const CallablePostCnt& post_cnt) {
- return CallablePostCnt({success += post_cnt.success, misses += post_cnt.misses});
- }
-};
-
-// Provide a client user of the stack manager module services
-class Client {
-public:
- Client(int id) : id_(id) {}
- Client(const Client&) = default;
- virtual ~Client() = default;
-
- // Start up the client a thread and handler
- void Start() {
- thread_ = new os::Thread(common::StringFormat("ClientThread%d", id_),
- os::Thread::Priority::NORMAL);
- handler_ = new os::Handler(thread_);
- handler_->Post(
- common::BindOnce([](int id) { log::info("<=== tid Started client id:{}", id); }, id_));
- }
-
- // Ensure all the client handlers are running
- void Await() {
- std::promise<void> promise;
- std::future future = promise.get_future();
- handler_->Post(base::BindOnce([](std::promise<void> promise) { promise.set_value(); },
- std::move(promise)));
- future.wait();
- }
-
- // Post a work task on behalf of this client
- void Post(common::OnceClosure closure) {
- if (quiesced_) {
- post_cnt_.misses++;
- } else {
- post_cnt_.success++;
- handler_->Post(std::move(closure));
- }
- }
-
- // Safely prevent new work tasks from being posted
- void Quiesce() {
- if (quiesced_) {
- return;
- }
- quiesced_ = true;
- std::promise promise = std::promise<void>();
- std::future future = promise.get_future();
- handler_->Post(common::BindOnce(
- [](std::promise<void> promise, int id) {
- promise.set_value();
- log::info("<=== tid Quiesced client id:{}", id);
- },
- std::move(promise), id_));
- future.wait_for(std::chrono::milliseconds(kSyncMainLoopTimeoutMs));
- }
-
- // Queisces if needed and stops the client then releases associated resources
- void Stop() {
- if (!quiesced_) {
- Quiesce();
- }
- handler_->Clear();
- handler_->WaitUntilStopped(std::chrono::milliseconds(kWaitUntilHandlerStoppedMs));
- delete handler_;
- delete thread_;
- }
-
- int Id() const { return id_; }
-
- CallablePostCnt GetCallablePostCnt() const { return post_cnt_; }
-
- std::string Name() const { return common::StringFormat("%s%d", __func__, id_); }
-
-private:
- int id_{0};
- CallablePostCnt post_cnt_{};
- bool quiesced_{false};
- os::Handler* handler_{nullptr};
- os::Thread* thread_{nullptr};
-};
-
-// Convenience object to handle multiple clients with logging
-class ClientGroup {
-public:
- explicit ClientGroup(size_t num_clients) {
- for (size_t i = 0; i < num_clients; i++) {
- clients_.emplace_back(std::make_unique<Client>(i));
- }
- }
-
- void Start() {
- log_tag(kLogTagStarting);
- for (auto& c : clients_) {
- c->Start();
- }
- }
-
- void Await() {
- for (auto& c : clients_) {
- c->Await();
- }
- log_tag(kLogTagStarted);
- }
-
- void Quiesce() {
- log_tag(kLogTagQuiescing);
- for (auto& c : clients_) {
- c->Quiesce();
- }
- log_tag(kLogTagQuiesced);
- }
-
- void Stop() {
- for (auto& c : clients_) {
- c->Stop();
- }
- log_tag(kLogTagStopped);
- }
-
- void Dump() const {
- for (auto& c : clients_) {
- log::info("Callable post cnt client_id:{} success:{} misses:{}", c->Id(),
- c->GetCallablePostCnt().success, c->GetCallablePostCnt().misses);
- }
- }
-
- CallablePostCnt GetCallablePostCnt() const {
- CallablePostCnt post_cnt{};
- for (auto& c : clients_) {
- post_cnt += c->GetCallablePostCnt();
- }
- return post_cnt;
- }
-
- size_t NumClients() const { return clients_.size(); }
-
- std::vector<std::unique_ptr<Client>> clients_;
-};
-
-class MainShimStackDumpsysWithClientsTest : public MainShimStackDumpsysTest {
-protected:
- void SetUp() override {
- MainShimStackDumpsysTest::SetUp();
- client_group_.Start();
- client_group_.Await();
- }
-
- void TearDown() override {
- client_group_.Quiesce();
- client_group_.Stop();
- MainShimStackDumpsysTest::TearDown();
- }
- ClientGroup client_group_ = ClientGroup(kNumTestClients);
-};
-
-TEST_F(MainShimStackDumpsysWithClientsTest, all_clients_check_stack_running) {
- StackRunningData stack_running_data = {
- .cb =
- [](bool is_stack_running) {
- log::info("Stack is running:{}", (is_stack_running) ? 'T' : 'F');
- },
- };
-
- // Ensure the dumpsys instance is included within the stack
- ASSERT_NE(nullptr, bluetooth::shim::GetDumpsys());
-
- for (auto& c : client_group_.clients_) {
- c->Post(base::BindOnce(
- [](StackRunningData stack_running_data) {
- bluetooth::shim::Stack::GetInstance()
- ->GetStackManager()
- ->GetInstance<TestStackDumpsys1>()
- ->IsStackRunning(stack_running_data);
- },
- stack_running_data));
- }
-}
-
-TEST_F(MainShimStackDumpsysWithClientsTest, all_clients_check_stack_running_with_iterations) {
- StackRunningData stack_running_data = {
- .cb =
- [](bool is_stack_running) {
- log::info("Run on mainloop: Stack is running:{}",
- (is_stack_running) ? 'T' : 'F');
- },
- };
-
- // Ensure the dumpsys instance is included within the stack
- ASSERT_NE(nullptr, bluetooth::shim::GetDumpsys());
-
- for (int i = 0; i < 2; i++) {
- log::info("Iteration:{}", i);
- for (auto& c : client_group_.clients_) {
- c->Post(base::BindOnce(
- [](StackRunningData stack_running_data) {
- bluetooth::shim::Stack::GetInstance()
- ->GetStackManager()
- ->GetInstance<TestStackDumpsys1>()
- ->IsStackRunning(stack_running_data);
- },
- stack_running_data));
- }
- }
-}
-
-TEST_F(MainShimStackDumpsysWithClientsTest, dumpsys_single_client) {
- // Ensure the dumpsys instance is included within the stack
- ASSERT_NE(nullptr, bluetooth::shim::GetDumpsys());
-
- const int fd = 1;
- client_group_.clients_[0]->Post(
- base::BindOnce([](int fd) { bluetooth::shim::Dump(fd, nullptr); }, fd));
-}
-
-TEST_F(MainShimStackDumpsysWithClientsTest, dumpsys_single_client_with_running_check) {
- StackRunningData stack_running_data = {
- .cb =
- [](bool is_stack_running) {
- log::info("Stack is running:{}", (is_stack_running) ? 'T' : 'F');
- },
- };
-
- // Ensure the dumpsys instance is included within the stack
- ASSERT_NE(nullptr, bluetooth::shim::GetDumpsys());
-
- const int fd = 1;
- client_group_.clients_[0]->Post(base::BindOnce(
- [](StackRunningData stack_running_data) {
- bluetooth::shim::Stack::GetInstance()
- ->GetStackManager()
- ->GetInstance<TestStackDumpsys1>()
- ->IsStackRunning(stack_running_data);
- },
- stack_running_data));
- client_group_.clients_[0]->Post(
- base::BindOnce([](int fd) { bluetooth::shim::Dump(fd, nullptr); }, fd));
-}
-
-TEST_F(MainShimStackDumpsysWithClientsTest, dumpsys_many_clients) {
- StackRunningData stack_running_data = {
- .cb =
- [](bool is_stack_running) {
- log::info("Stack is running:{}", (is_stack_running) ? 'T' : 'F');
- },
- };
-
- const int fd = 1;
- for (auto& c : client_group_.clients_) {
- c->Post(base::BindOnce([](int fd) { bluetooth::shim::Dump(fd, nullptr); }, fd));
- }
-}
diff --git a/system/main/test/main_shim_stack_lifecycle_test.cc b/system/main/test/main_shim_stack_lifecycle_test.cc
deleted file mode 100644
index 1720574218..0000000000
--- a/system/main/test/main_shim_stack_lifecycle_test.cc
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <bluetooth/log.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-
-#include <atomic>
-#include <cstdlib>
-#include <memory>
-#include <thread>
-
-#include "common/strings.h"
-#include "gd/module_jniloop.h"
-#include "gd/module_mainloop.h"
-#include "main/shim/stack.h"
-#include "module.h"
-#include "os/thread.h"
-#include "stack/include/main_thread.h"
-#include "test/mock/mock_main_shim_entry.h"
-
-using ::testing::_;
-
-using namespace bluetooth;
-using namespace testing;
-
-namespace {
-constexpr int kSyncMainLoopTimeoutMs = 3000;
-constexpr int kWaitUntilHandlerStoppedMs = 2000;
-constexpr size_t kNumTestClients = 3;
-constexpr size_t kNumTestModules = 3;
-constexpr int kNumIters = 100;
-constexpr int kAbruptStackShutdownIter = kNumIters * 3 / 4;
-constexpr char kTestStackThreadName[] = "test_stack_thread";
-constexpr char kTestDataTag[] = "This is a test";
-
-inline void maybe_yield() {
- if (std::rand() & 1) {
- std::this_thread::yield();
- }
-}
-
-constexpr size_t kTagLength = 48 + sizeof(' ') + sizeof(' ');
-inline void log_tag(std::string tag) {
- std::string prepend(kTagLength / 2 - tag.size() / 2, '=');
- std::string append(kTagLength / 2 - tag.size() / 2, '=');
- log::info("{} {} {}", prepend, tag, append);
-}
-
-class MainThread {
-public:
- MainThread() { main_thread_start_up(); }
-
- ~MainThread() {
- sync_main_handler();
- main_thread_shut_down();
- }
-
-private:
- void sync_main_handler() {
- std::promise promise = std::promise<void>();
- std::future future = promise.get_future();
- post_on_bt_main([&promise]() { promise.set_value(); });
- future.wait_for(std::chrono::milliseconds(kSyncMainLoopTimeoutMs));
- }
-};
-
-class TestStackManager {
-public:
- TestStackManager() {
- // Start is executed by the test after each test adds the default
- // or their own modules
- }
-
- ~TestStackManager() {
- log::debug("Deleting stack manager");
- Stop();
- }
-
- TestStackManager(const TestStackManager&) = delete;
-
- template <typename T>
- void AddModule() {
- modules_.add<T>();
- }
-
- void Start() {
- if (stack_started_) {
- return;
- }
- log::info("Started stack manager");
- stack_started_ = true;
- bluetooth::os::Thread* stack_thread = new bluetooth::os::Thread(
- kTestStackThreadName, bluetooth::os::Thread::Priority::NORMAL);
- bluetooth::shim::Stack::GetInstance()->StartModuleStack(&modules_, stack_thread);
- }
-
- void Stop() {
- if (!stack_started_) {
- return;
- }
- stack_started_ = false;
- bluetooth::shim::Stack::GetInstance()->Stop();
- }
-
- // NOTE: Stack manager *must* be active else method returns nullptr
- // if stack manager has not started or shutdown
- template <typename T>
- static T* GetUnsafeModule() {
- return bluetooth::shim::Stack::GetInstance()->GetStackManager()->GetInstance<T>();
- }
-
- size_t NumModules() const { return modules_.NumModules(); }
-
-private:
- bluetooth::ModuleList modules_;
- bool stack_started_{false};
-};
-
-// Data returned via callback from a stack managed module
-struct TestCallbackData {
- int iter;
- std::string tag;
-};
-
-// Data sent to a stack managed module via a module API
-struct TestData {
- int iter;
- std::string tag;
- std::function<void(TestCallbackData callback_data)> callback;
-};
-
-class TestStackModuleBase : public bluetooth::Module, public ModuleMainloop, public ModuleJniloop {
-public:
- TestStackModuleBase(const TestStackModuleBase&) = delete;
- TestStackModuleBase& operator=(const TestStackModuleBase&) = delete;
-
- virtual ~TestStackModuleBase() {}
- static const ModuleFactory Factory;
-
- virtual void TestMethod(TestData test_data) const {
- log::info("Test base class iter:{} tag:{}", test_data.iter, test_data.tag);
- }
-
-protected:
- void ListDependencies(ModuleList* /*list*/) const override {}
- void Start() override { log::error("Started TestStackModuleBase"); }
- void Stop() override { log::error("Stopped TestStackModuleBase"); }
- std::string ToString() const override { return std::string("TestFunction"); }
-
- TestStackModuleBase() = default;
-};
-
-class TestStackModule1 : public TestStackModuleBase {
-public:
- TestStackModule1(const TestStackModule1&) = delete;
- TestStackModule1& operator=(const TestStackModule1&) = delete;
- virtual ~TestStackModule1() = default;
-
- static const ModuleFactory Factory;
-
- void TestMethod(TestData test_data) const override;
-
-private:
- struct impl;
- std::shared_ptr<impl> impl_;
- TestStackModule1();
-};
-
-struct TestStackModule1::impl : public ModuleMainloop, public ModuleJniloop {
- void test(TestData test_data) {
- TestCallbackData callback_data{
- .iter = test_data.iter,
- .tag = std::string(__func__),
- };
- PostFunctionOnMain([](std::function<void(TestCallbackData callback_data)> callback,
- TestCallbackData data) { callback(data); },
- test_data.callback, callback_data);
- }
-};
-
-TestStackModule1::TestStackModule1() : TestStackModuleBase() { impl_ = std::make_shared<impl>(); }
-
-void TestStackModule1::TestMethod(TestData test_data) const {
- PostMethodOnMain(impl_, &impl::test, test_data);
-}
-
-class TestStackModule2 : public TestStackModuleBase {
-public:
- TestStackModule2(const TestStackModule2&) = delete;
- TestStackModule2& operator=(const TestStackModule2&) = delete;
- virtual ~TestStackModule2() = default;
-
- static const ModuleFactory Factory;
-
- void TestMethod(TestData test_data) const override;
-
-private:
- struct impl;
- std::shared_ptr<impl> impl_;
- TestStackModule2();
-};
-
-struct TestStackModule2::impl : public ModuleMainloop, public ModuleJniloop {
- void test(TestData test_data) {
- TestCallbackData callback_data{
- .iter = test_data.iter,
- .tag = std::string(__func__),
- };
- PostFunctionOnMain([](std::function<void(TestCallbackData callback_data)> callback,
- TestCallbackData data) { callback(data); },
- test_data.callback, callback_data);
- }
-};
-
-TestStackModule2::TestStackModule2() : TestStackModuleBase() { impl_ = std::make_shared<impl>(); }
-
-void TestStackModule2::TestMethod(TestData test_data) const {
- PostMethodOnMain(impl_, &impl::test, test_data);
-}
-
-class TestStackModule3 : public TestStackModuleBase {
-public:
- TestStackModule3(const TestStackModule3&) = delete;
- TestStackModule3& operator=(const TestStackModule3&) = delete;
- virtual ~TestStackModule3() = default;
-
- static const ModuleFactory Factory;
-
- void TestMethod(TestData test_data) const override;
-
-private:
- struct impl;
- std::shared_ptr<impl> impl_;
- TestStackModule3();
-};
-
-struct TestStackModule3::impl : public ModuleMainloop, public ModuleJniloop {
- void test(TestData test_data) {
- TestCallbackData callback_data{
- .iter = test_data.iter,
- .tag = std::string(__func__),
- };
- PostFunctionOnMain([](std::function<void(TestCallbackData callback_data)> callback,
- TestCallbackData data) { callback(data); },
- test_data.callback, callback_data);
- }
-};
-
-TestStackModule3::TestStackModule3() : TestStackModuleBase() { impl_ = std::make_shared<impl>(); }
-
-void TestStackModule3::TestMethod(TestData test_data) const {
- PostMethodOnMain(impl_, &impl::test, test_data);
-}
-
-class TestStackModule4 : public TestStackModuleBase {
-public:
- TestStackModule4(const TestStackModule4&) = delete;
- TestStackModule4& operator=(const TestStackModule3&) = delete;
- virtual ~TestStackModule4() = default;
-
- static const ModuleFactory Factory;
-
- void TestMethod(TestData test_data) const override {
- log::info("mod:{} iter:{} tag:{}", __func__, test_data.iter, test_data.tag);
- }
-
-private:
- struct impl;
- std::shared_ptr<impl> impl_;
- TestStackModule4() : TestStackModuleBase() {}
-};
-
-struct TestStackModule4::impl : public ModuleMainloop, public ModuleJniloop {};
-
-} // namespace
-
-const ModuleFactory TestStackModuleBase::Factory =
- ModuleFactory([]() { return new TestStackModuleBase(); });
-
-const ModuleFactory TestStackModule1::Factory =
- ModuleFactory([]() { return new TestStackModule1(); });
-const ModuleFactory TestStackModule2::Factory =
- ModuleFactory([]() { return new TestStackModule2(); });
-const ModuleFactory TestStackModule3::Factory =
- ModuleFactory([]() { return new TestStackModule3(); });
-const ModuleFactory TestStackModule4::Factory =
- ModuleFactory([]() { return new TestStackModule4(); });
-
-class StackWithMainThreadUnitTest : public ::testing::Test {
-protected:
- void SetUp() override { main_thread_ = std::make_unique<MainThread>(); }
- void TearDown() override { main_thread_.reset(); }
-
-private:
- std::unique_ptr<MainThread> main_thread_;
-};
-
-class StackLifecycleUnitTest : public StackWithMainThreadUnitTest {
-public:
- std::shared_ptr<TestStackManager> StackManager() const { return stack_manager_; }
-
-protected:
- void SetUp() override {
- StackWithMainThreadUnitTest::SetUp();
- stack_manager_ = std::make_shared<TestStackManager>();
- }
-
- void TearDown() override {
- stack_manager_.reset();
- StackWithMainThreadUnitTest::TearDown();
- }
-
-private:
- std::shared_ptr<TestStackManager> stack_manager_;
-};
-
-TEST_F(StackLifecycleUnitTest, no_modules_in_stack) { ASSERT_EQ(0U, StackManager()->NumModules()); }
-
-class StackLifecycleWithDefaultModulesUnitTest : public StackLifecycleUnitTest {
-protected:
- void SetUp() override {
- StackLifecycleUnitTest::SetUp();
- StackManager()->AddModule<TestStackModule1>();
- StackManager()->AddModule<TestStackModule2>();
- StackManager()->AddModule<TestStackModule3>();
- StackManager()->Start();
- ASSERT_EQ(3U, StackManager()->NumModules());
- }
-
- void TearDown() override { StackLifecycleUnitTest::TearDown(); }
-};
-
-struct CallablePostCnt {
- size_t success{0};
- size_t misses{0};
- CallablePostCnt operator+=(const CallablePostCnt& post_cnt) {
- return CallablePostCnt({success += post_cnt.success, misses += post_cnt.misses});
- }
-};
-
-// Provide a client user of the stack manager module services
-class Client {
-public:
- Client(int id) : id_(id) {}
- Client(const Client&) = default;
- virtual ~Client() = default;
-
- // Start up the client a thread and handler
- void Start() {
- log::info("Started client {}", id_);
- thread_ = new os::Thread(common::StringFormat("ClientThread%d", id_),
- os::Thread::Priority::NORMAL);
- handler_ = new os::Handler(thread_);
- handler_->Post(common::BindOnce([](int id) { log::info("Started client {}", id); }, id_));
- }
-
- // Ensure all the client handlers are running
- void Await() {
- std::promise<void> promise;
- std::future future = promise.get_future();
- handler_->Post(base::BindOnce([](std::promise<void> promise) { promise.set_value(); },
- std::move(promise)));
- future.wait();
- }
-
- // Post a work task on behalf of this client
- void Post(common::OnceClosure closure) {
- if (quiesced_) {
- post_cnt_.misses++;
- maybe_yield();
- } else {
- post_cnt_.success++;
- handler_->Post(std::move(closure));
- maybe_yield();
- }
- }
-
- // Safely prevent new work tasks from being posted
- void Quiesce() {
- if (quiesced_) {
- return;
- }
- quiesced_ = true;
- std::promise promise = std::promise<void>();
- std::future future = promise.get_future();
- handler_->Post(common::BindOnce([](std::promise<void> promise) { promise.set_value(); },
- std::move(promise)));
- future.wait_for(std::chrono::milliseconds(kSyncMainLoopTimeoutMs));
- }
-
- // Stops the client and associated resources
- void Stop() {
- if (!quiesced_) {
- Quiesce();
- }
- handler_->Clear();
- handler_->WaitUntilStopped(std::chrono::milliseconds(kWaitUntilHandlerStoppedMs));
- delete handler_;
- delete thread_;
- }
-
- int Id() const { return id_; }
-
- CallablePostCnt GetCallablePostCnt() const { return post_cnt_; }
-
- std::string Name() const { return common::StringFormat("%s%d", __func__, id_); }
-
-private:
- int id_{0};
- CallablePostCnt post_cnt_{};
- bool quiesced_{false};
- os::Handler* handler_{nullptr};
- os::Thread* thread_{nullptr};
-};
-
-// Convenience object to handle multiple clients with logging
-class ClientGroup {
-public:
- ClientGroup() {}
-
- void Start() {
- for (auto& c : clients_) {
- c->Start();
- }
- log_tag("STARTING");
- }
-
- void Await() {
- for (auto& c : clients_) {
- c->Await();
- }
- log_tag("STARTED");
- }
-
- void Quiesce() {
- log_tag("QUIESCING");
- for (auto& c : clients_) {
- c->Quiesce();
- }
- log_tag("QUIESCED");
- }
-
- void Stop() {
- for (auto& c : clients_) {
- c->Stop();
- }
- log_tag("STOPPED");
- }
-
- void Dump() const {
- for (auto& c : clients_) {
- log::info("Callable post cnt client_id:{} success:{} misses:{}", c->Id(),
- c->GetCallablePostCnt().success, c->GetCallablePostCnt().misses);
- }
- }
-
- CallablePostCnt GetCallablePostCnt() const {
- CallablePostCnt post_cnt{};
- for (auto& c : clients_) {
- post_cnt += c->GetCallablePostCnt();
- }
- return post_cnt;
- }
-
- size_t NumClients() const { return kNumTestClients; }
-
- std::unique_ptr<Client> clients_[kNumTestClients] = {
- std::make_unique<Client>(1), std::make_unique<Client>(2), std::make_unique<Client>(3)};
-};
-
-TEST_F(StackLifecycleWithDefaultModulesUnitTest, clients_start) {
- ClientGroup client_group;
-
- client_group.Start();
- client_group.Await();
-
- // Clients are operational
-
- client_group.Quiesce();
- client_group.Stop();
-}
-
-TEST_F(StackLifecycleWithDefaultModulesUnitTest, client_using_stack_manager) {
- ClientGroup client_group;
- client_group.Start();
- client_group.Await();
-
- for (int i = 0; i < kNumIters; i++) {
- for (auto& c : client_group.clients_) {
- c->Post(base::BindOnce(
- [](int /*id*/, int iter, std::shared_ptr<TestStackManager> stack_manager) {
- stack_manager->GetUnsafeModule<TestStackModule1>()->TestMethod({
- .iter = iter,
- .tag = std::string(kTestDataTag),
- .callback = [](TestCallbackData /*data*/) {},
- });
- },
- c->Id(), i, StackManager()));
- c->Post(base::BindOnce(
- [](int /*id*/, int iter, std::shared_ptr<TestStackManager> stack_manager) {
- stack_manager->GetUnsafeModule<TestStackModule2>()->TestMethod({
- .iter = iter,
- .tag = std::string(kTestDataTag),
- .callback = [](TestCallbackData /*data*/) {},
- });
- },
- c->Id(), i, StackManager()));
- c->Post(base::BindOnce(
- [](int /*id*/, int iter, std::shared_ptr<TestStackManager> stack_manager) {
- stack_manager->GetUnsafeModule<TestStackModule3>()->TestMethod({
- .iter = iter,
- .tag = std::string(kTestDataTag),
- .callback = [](TestCallbackData /*data*/) {},
- });
- },
- c->Id(), i, StackManager()));
- }
- }
-
- client_group.Quiesce();
- client_group.Stop();
- client_group.Dump();
-
- ASSERT_EQ(client_group.NumClients() * kNumIters * kNumTestModules,
- client_group.GetCallablePostCnt().success + client_group.GetCallablePostCnt().misses);
-}
-
-TEST_F(StackLifecycleWithDefaultModulesUnitTest, client_using_stack_manager_when_shutdown) {
- struct Counters {
- struct {
- std::atomic_size_t cnt{0};
- } up, down;
- } counters;
-
- ClientGroup client_group;
- client_group.Start();
- client_group.Await();
-
- for (int i = 0; i < kNumIters; i++) {
- for (auto& c : client_group.clients_) {
- c->Post(base::BindOnce(
- [](int /*id*/, int iter, Counters* counters,
- std::shared_ptr<TestStackManager> /*stack_manager*/) {
- TestData test_data = {
- .iter = iter,
- .tag = std::string(kTestDataTag),
- .callback = [](TestCallbackData /*data*/) {},
- };
- if (bluetooth::shim::Stack::GetInstance()->CallOnModule<TestStackModule1>(
- [test_data](TestStackModule1* mod) { mod->TestMethod(test_data); })) {
- counters->up.cnt++;
- } else {
- counters->down.cnt++;
- }
- },
- c->Id(), i, &counters, StackManager()));
- c->Post(base::BindOnce(
- [](int /*id*/, int iter, Counters* counters,
- std::shared_ptr<TestStackManager> /*stack_manager*/) {
- TestData test_data = {
- .iter = iter,
- .tag = std::string(kTestDataTag),
- .callback = [](TestCallbackData /*data*/) {},
- };
- if (bluetooth::shim::Stack::GetInstance()->CallOnModule<TestStackModule2>(
- [test_data](TestStackModule2* mod) { mod->TestMethod(test_data); })) {
- counters->up.cnt++;
- } else {
- counters->down.cnt++;
- }
- },
- c->Id(), i, &counters, StackManager()));
- c->Post(base::BindOnce(
- [](int /*id*/, int iter, Counters* counters,
- std::shared_ptr<TestStackManager> /*stack_manager*/) {
- TestData test_data = {
- .iter = iter,
- .tag = std::string(kTestDataTag),
- .callback = [](TestCallbackData /*data*/) {},
- };
- if (bluetooth::shim::Stack::GetInstance()->CallOnModule<TestStackModule3>(
- [test_data](TestStackModule3* mod) { mod->TestMethod(test_data); })) {
- counters->up.cnt++;
- } else {
- counters->down.cnt++;
- }
- },
- c->Id(), i, &counters, StackManager()));
- }
- // Abruptly shutdown stack at some point through the iterations
- if (i == kAbruptStackShutdownIter) {
- log_tag("SHUTTING DOWN STACK");
- StackManager()->Stop();
- }
- }
-
- client_group.Quiesce();
- client_group.Stop();
- log::info("Execution stack availability counters up:{} down:{}", counters.up.cnt,
- counters.down.cnt);
-
- ASSERT_EQ(client_group.NumClients() * kNumIters * kNumTestModules,
- client_group.GetCallablePostCnt().success + client_group.GetCallablePostCnt().misses);
-}
diff --git a/system/stack/Android.bp b/system/stack/Android.bp
index 25cf3c5a5d..cb987debfc 100644
--- a/system/stack/Android.bp
+++ b/system/stack/Android.bp
@@ -813,7 +813,6 @@ cc_test {
"libbase",
"libbluetooth-dumpsys",
"libbluetooth-for-tests",
- "libbluetooth-gdx",
"libbluetooth-types",
"libbluetooth_core_rs",
"libbluetooth_crypto_toolbox",
diff --git a/system/stack/test/fuzzers/Android.bp b/system/stack/test/fuzzers/Android.bp
index 8d146834d6..3c74de632d 100644
--- a/system/stack/test/fuzzers/Android.bp
+++ b/system/stack/test/fuzzers/Android.bp
@@ -40,7 +40,6 @@ cc_defaults {
"bluetooth_flags_c_lib",
"libFraunhoferAAC",
"libbluetooth-dumpsys",
- "libbluetooth-gdx",
"libbluetooth-types",
"libbluetooth_core_rs",
"libbluetooth_crypto_toolbox",
diff --git a/system/test/headless/Android.bp b/system/test/headless/Android.bp
index 9e0a234742..846f9ec4cc 100644
--- a/system/test/headless/Android.bp
+++ b/system/test/headless/Android.bp
@@ -82,7 +82,6 @@ cc_binary {
"libFraunhoferAAC",
"libbase",
"libbluetooth-dumpsys",
- "libbluetooth-gdx",
"libbluetooth-types",
"libbluetooth_core_rs",
"libbluetooth_crypto_toolbox",
diff --git a/system/test/suite/Android.bp b/system/test/suite/Android.bp
index 4ce6367d5b..09e8fda413 100644
--- a/system/test/suite/Android.bp
+++ b/system/test/suite/Android.bp
@@ -121,7 +121,6 @@ cc_test {
],
static_libs: [
"bluetooth_flags_c_lib_for_test",
- "libbluetooth-gdx",
"libbluetooth_crypto_toolbox",
"libbluetooth_gd",
"libbluetooth_hci_pdl",