1. 背景
上一章節 我們介紹了 module_t 的 大體框架 ,本節內容我們就選擇 我們的 gd_shim_module 模塊為例子,具體剖析一下,它里面的邏輯。
static const char GD_SHIM_MODULE[] = "gd_shim_module";// system/main/shim/shim.cc
EXPORT_SYMBOL extern const module_t gd_shim_module = {.name = GD_SHIM_MODULE,.init = kUnusedModuleApi,.start_up = ShimModuleStartUp,.shut_down = GeneralShutDown,.clean_up = kUnusedModuleApi,.dependencies = {kUnusedModuleDependencies}};
-
從上述代碼可以知道, gd_shim_module 模塊只有 start_up 和 shut_down 兩個階段。而且他不依賴任何模塊。
-
gd_shim_module 的作用:
作為?新舊藍牙協議棧的兼容層(Shim Layer)。- 將傳統的 Bluedroid 接口適配到新的 GD(Google Direct)架構。
-
設計原因:
漸進式重構藍牙協議棧時,確保舊代碼(如 Android 傳統藍牙服務)能無縫調用新模塊。
生命周期:
- 在 event_start_up_stack 階段 調用 start_up , 實際調用 ShimModuleStartUp
- 在 event_shut_down_stack 階段 調用 shut_down, 實際調用 GeneralShutDown
那接下來我們就一起分析一下 他的 start_up 和 shut_down 中分別做了那些事情。
// system/main/shim/shim.cc
future_t* ShimModuleStartUp() {bluetooth::shim::Stack::GetInstance()->StartEverything();return kReturnImmediate;
}
// system/main/shim/stack.cc
Stack* Stack::GetInstance() {static Stack instance;return &instance;
}
-
從 Stack::GetInstance 函數中,我們不難發現, 他此時獲取的 是一個 局部靜態 變量 Stack 對象。 類似是一種單例的實現方式。
-
無論誰先調用 bluetooth::shim::Stack::GetInstance() 都將拿到 同一個 Stack 對象 。
-
ShimModuleStartUp() 函數其實調用的 Stack 對象的 StartEverything() 方法。
既然這里提到了 bluetooth::shim::Stack ,那我們不妨先來看一下他的數據結構。
2. bluetooth::shim::Stack
// The shim layer implementation on the Gd stack side.
namespace bluetooth {
namespace shim {// GD shim stack, having modes corresponding to legacy stack
class Stack {public:static Stack* GetInstance();Stack() = default;Stack(const Stack&) = delete;Stack& operator=(const Stack&) = delete;~Stack() = default;// Idle mode, config is loaded, but controller is not enabledvoid StartIdleMode();// Running mode, everything is upvoid StartEverything();void Stop();bool IsRunning();bool IsDumpsysModuleStarted() const;StackManager* GetStackManager();const StackManager* GetStackManager() const;legacy::Acl* GetAcl();LinkPolicyInterface* LinkPolicy();Btm* GetBtm();os::Handler* GetHandler();::rust::Box<rust::Hci>* GetRustHci() { return rust_hci_; }::rust::Box<rust::Controller>* GetRustController() {return rust_controller_;}private:mutable std::recursive_mutex mutex_;StackManager stack_manager_; // 管理 GD 協議棧中所有藍牙模塊的生命周期bool is_running_ = false;os::Thread* stack_thread_ = nullptr; // 為整個藍牙協議棧提供專用的執行線程os::Handler* stack_handler_ = nullptr; // 提供消息處理機制,用于線程間通信和任務調度legacy::Acl* acl_ = nullptr;Btm* btm_ = nullptr;::rust::Box<rust::Stack>* rust_stack_ = nullptr;::rust::Box<rust::Hci>* rust_hci_ = nullptr;::rust::Box<rust::Controller>* rust_controller_ = nullptr;void Start(ModuleList* modules);
};} // namespace shim
} // namespace bluetooth
Stack
?類是 藍牙協議棧中的核心管理類,負責實現新的 GD (Google Direct) 藍牙協議棧。它充當傳統藍牙協議棧和新模塊化 GD 架構之間的橋梁。
1. 關鍵成員講解
1. stack_manager_
StackManager stack_manager_;
-
作用:管理 GD 協議棧中所有藍牙模塊的生命周期
-
職責:
- 以正確的順序啟動和關閉模塊
- 提供對模塊實例的訪問
- 維護模塊間的依賴關系
-
與其他組件的關系:
Stack
?類擁有并控制?StackManager
,用它來初始化和管理所有藍牙模塊
2.?stack_thread_
?(os::Thread)
-
作用:為整個藍牙協議棧提供專用的執行線程
-
特點:
- 被設置為實時優先級(REAL_TIME)
- 命名為"gd_stack_thread"
-
與其他組件的關系:
- 由?
Stack
?類創建和管理 - 為?
stack_handler_
?提供運行環境 - 被?
StackManager
?用來調度模塊任務
- 由?
3.?stack_handler_
?(os::Handler)
-
作用:提供消息處理機制,用于線程間通信和任務調度
-
特點:
- 與?
stack_thread_
?關聯 - 用于處理異步操作和事件
- 與?
-
與其他組件的關系:
- 由?
Stack
?類創建并與?stack_thread_
?綁定 - 被多個模塊(如 ACL)用來發送和接收消息
- 由?
4.?ModuleList*
-
作用:包含需要啟動的藍牙模塊集合
-
特點:
- 根據不同的啟動模式(Idle/Everything)包含不同的模塊
- 使用 add<>() 方法動態添加模塊
-
與其他組件的關系:
- 被傳遞給?
StackManager
?的 StartUp 方法 - 決定了哪些模塊會被初始化和運行
- 被傳遞給?
2. Stack 類的主要功能
-
協議棧生命周期管理:
StartIdleMode()
?- 啟動最小配置(僅基礎模塊)StartEverything()
?- 啟動完整協議棧功能Stop()
?- 關閉協議棧
-
資源管理:
- 創建和管理 PID 文件
- 確保資源的正確初始化和釋放
-
模塊訪問接口:
- 提供獲取各種模塊實例的方法(如 GetAcl(), GetBtm())
-
兼容層支持:
- 維護與傳統協議棧的兼容接口
3.這么設計的好處
-
模塊化設計:
- 將藍牙功能分解為獨立模塊,便于維護和擴展
- 允許按需加載模塊,減少資源占用
-
線程安全:
- 使用遞歸互斥鎖(mutex_)保護共享資源
- 確保多線程環境下的安全訪問
-
靈活配置:
- 通過?
ModuleList
?支持不同配置(如僅核心功能或完整功能) - 根據系統標志(gd_rust_is_enabled 等)動態調整行為
- 通過?
-
平滑過渡:
- 提供與傳統協議棧兼容的接口
- 支持新舊實現共存
-
資源控制:
- 集中管理線程和消息處理程序
- 確保資源正確初始化和釋放
這種設計使得藍牙協議棧更加靈活、可維護,并且能夠平滑地從傳統實現過渡到新的 GD 架構,同時保持對現有應用的兼容性。
3. ShimModuleStartUp
上面我已經 為大家介紹了 Stack 數據結構, 或許你還有對 Stack 有其他疑問, 但不要著急, 我們一起來繼續分析 我們 gd_shim_module 模塊的 start_up 階段。在這個過程中我們來不斷體會 Stack 數據結構設計的巧妙之處。
// system/main/shim/shim.cc
future_t* ShimModuleStartUp() {bluetooth::shim::Stack::GetInstance()->StartEverything();return kReturnImmediate;
}
// system/main/shim/stack.cc
Stack* Stack::GetInstance() {static Stack instance;return &instance;
}
-
從 Stack::GetInstance 函數中,我們不難發現, 他此時獲取的 是一個 局部靜態 變量 Stack 對象。 類似是一種單例的實現方式。
-
無論誰先調用 bluetooth::shim::Stack::GetInstance() 都將拿到 同一個 Stack 對象 。
-
ShimModuleStartUp() 函數其實調用的 Stack 對象的 StartEverything() 方法。
3.1 Stack::StartEverything
void Stack::StartEverything() {// 1. **Rust路徑**:當`gd_rust_is_enabled()`標志為真時,使用Rust實現的協議棧if (common::init_flags::gd_rust_is_enabled()) {if (rust_stack_ == nullptr) {rust_stack_ = new ::rust::Box<rust::Stack>(rust::stack_create());}rust::stack_start(**rust_stack_);// 獲取HCI和Controller組件實例// 這些組件由Rust實現,通過FFI接口暴露給C++rust_hci_ = new ::rust::Box<rust::Hci>(rust::get_hci(**rust_stack_));rust_controller_ =new ::rust::Box<rust::Controller>(rust::get_controller(**rust_stack_));bluetooth::shim::hci_on_reset_complete();// Create pid since we're up and runningCreatePidFile();// Create the acl shim layeracl_ = new legacy::Acl(stack_handler_, legacy::GetAclInterface(),controller_get_interface()->get_ble_acceptlist_size(),controller_get_interface()->get_ble_resolving_list_max_size());return;}// 傳統C++ 實現的 GD協議棧, 我們以 C++ 實現的分析為主// 使用遞歸鎖保護整個啟動過程// 防止多線程并發訪問導致狀態不一致std::lock_guard<std::recursive_mutex> lock(mutex_);ASSERT_LOG(!is_running_, "%s Gd stack already running", __func__);LOG_INFO("%s Starting Gd stack", __func__);// 方法通過`ModuleList`動態添加各種藍牙模塊:ModuleList modules;modules.add<metrics::CounterMetrics>();modules.add<hal::HciHal>();modules.add<hci::HciLayer>();modules.add<storage::StorageModule>();modules.add<shim::Dumpsys>();modules.add<hci::VendorSpecificEventManager>();modules.add<hci::Controller>();modules.add<hci::AclManager>();// 添加L2CAP相關模塊if (common::init_flags::gd_l2cap_is_enabled()) {modules.add<l2cap::classic::L2capClassicModule>();modules.add<l2cap::le::L2capLeModule>();modules.add<hci::LeAdvertisingManager>();}// 添加安全模塊if (common::init_flags::gd_security_is_enabled()) {modules.add<security::SecurityModule>();}modules.add<hci::LeAdvertisingManager>();modules.add<hci::LeScanningManager>();// 添加活動追蹤模塊if (common::init_flags::btaa_hci_is_enabled()) {modules.add<activity_attribution::ActivityAttribution>();}// 添加核心功能模塊if (common::init_flags::gd_core_is_enabled()) {modules.add<att::AttModule>();modules.add<neighbor::ConnectabilityModule>();modules.add<neighbor::DiscoverabilityModule>();modules.add<neighbor::InquiryModule>();modules.add<neighbor::NameModule>();modules.add<neighbor::NameDbModule>();modules.add<neighbor::PageModule>();modules.add<neighbor::ScanModule>();modules.add<storage::StorageModule>();}// 根據上述的模塊, 來實際啟動協議棧Start(&modules);is_running_ = true; // 設置運行標志// 驗證關鍵模塊是否成功啟動// Make sure the leaf modules are startedASSERT(stack_manager_.GetInstance<storage::StorageModule>() != nullptr);ASSERT(stack_manager_.GetInstance<shim::Dumpsys>() != nullptr);if (common::init_flags::gd_core_is_enabled()) {btm_ = new Btm(stack_handler_,stack_manager_.GetInstance<neighbor::InquiryModule>());}// 為傳統API提供兼容層支持// 確保新舊實現可以協同工作if (!common::init_flags::gd_core_is_enabled()) {if (stack_manager_.IsStarted<hci::Controller>()) {acl_ = new legacy::Acl(stack_handler_, legacy::GetAclInterface(),controller_get_interface()->get_ble_acceptlist_size(),controller_get_interface()->get_ble_resolving_list_max_size());} else {LOG_ERROR("Unable to create shim ACL layer as Controller has not started");}}if (!common::init_flags::gd_core_is_enabled()) {bluetooth::shim::hci_on_reset_complete();}bluetooth::shim::init_advertising_manager();bluetooth::shim::init_scanning_manager();if (common::init_flags::gd_l2cap_is_enabled() &&!common::init_flags::gd_core_is_enabled()) {L2CA_UseLegacySecurityModule();}if (common::init_flags::btaa_hci_is_enabled()) {bluetooth::shim::init_activity_attribution();}// Create pid since we're up and runningCreatePidFile();
}
- StartEverything 我們主要分析 C++ 的流程。
主要完成如下功能:
- 向 modules 中添加 需要的模塊:例如 hal::HciHal 模塊和 hci::HciLayer
- 調用 Start(&modules) 來啟動這些模塊
- 初始化兼容層組件
- 創建PID文件標記啟動完成
這種方法設計既支持新特性的逐步引入,又保持了與傳統實現的兼容性,是大型系統漸進式重構的典型范例。
設計特點分析:
-
條件編譯支持:
- 通過功能標志控制代碼路徑和模塊加載
- 實現靈活的功能組合
-
模塊化設計:
- 每個功能作為獨立模塊添加
- 模塊間通過定義良好的接口交互
-
漸進式遷移:
- 支持Rust和C++實現并存
- 兼容層確保平穩過渡
-
生命周期管理:
- 明確的啟動順序控制
- 關鍵資源的狀態驗證
-
診斷支持:
- PID文件記錄運行狀態
- 豐富的日志輸出
3.2 Stack::Start
我們來看一下 是如何將加入 modules 中的模塊,啟動起來的。
void Stack::Start(ModuleList* modules) {ASSERT_LOG(!is_running_, "%s Gd stack already running", __func__);LOG_INFO("%s Starting Gd stack", __func__);stack_thread_ =new os::Thread("gd_stack_thread", os::Thread::Priority::REAL_TIME);stack_manager_.StartUp(modules, stack_thread_);stack_handler_ = new os::Handler(stack_thread_);LOG_INFO("%s Successfully toggled Gd stack", __func__);
}
- 首先這里創建了 gd_stack_thread 線程,
- 將 我們的 modules 信息 和 stack_thread_ 線程全部傳遞給了 stack_manager_, 從這里就能看出來, 我們前面添加的 模塊,全部由 StackManager 管理, 而且這些模塊,全部都是工作在 gd_stack_thread線程中的。
- 將我們 gd_stack_thread 對應的 handler 保存在 stack_handler_ 中。
我們來繼續分析 stack_manager_.StartUp(modules, stack_thread_);
3.3 StackManager::StartUp
- system/gd/stack_manager.cc
void StackManager::StartUp(ModuleList* modules, Thread* stack_thread) {// 這里有創建了一個線程 management_threadmanagement_thread_ = new Thread("management_thread", Thread::Priority::NORMAL);// 獲取到 management_thread 的 handlerhandler_ = new Handler(management_thread_);WakelockManager::Get().Acquire();std::promise<void> promise;auto future = promise.get_future();// 將 modules 的初始化全部 交給 management_thread 線程 來處理, handler_->Post(common::BindOnce(&StackManager::handle_start_up, common::Unretained(this), modules, stack_thread,std::move(promise)));// 然后 bt_stack_manager_thread 線程在這里等待 4 s, 讓所有加入的模塊,都初始化完成。LOG_INFO("init wait 4s.");auto init_status = future.wait_for(std::chrono::seconds(4));WakelockManager::Get().Release();// 如果 4s 后, init_status == std::future_status::ready 表明,所有的模塊都已經初始化完成。 ASSERT_LOG(init_status == std::future_status::ready,"Can't start stack, last instance: %s",registry_.last_instance_.c_str());LOG_INFO("init complete");
}
- 我們 modules 的初始化 全部交給 management_thread 的 StackManager::handle_start_up 函數來處理了, 我們繼續分析。
3.4 StackManager::handle_start_up
// system/gd/stack_manager.cc
void StackManager::handle_start_up(ModuleList* modules, Thread* stack_thread, std::promise<void> promise) {// 最終給到了 registry_.Start 來處理registry_.Start(modules, stack_thread);promise.set_value();
}
3.5 ModuleRegistry::Start
- system/gd/module.cc
void ModuleRegistry::Start(ModuleList* modules, Thread* thread) {for (auto it = modules->list_.begin(); it != modules->list_.end(); it++) {Start(*it, thread); // 從 modules 拿出每一個 module, 調用 Start}
}
Module* ModuleRegistry::Start(const ModuleFactory* module, Thread* thread) {// 從 started_modules_ 中查找, 當前的 module 是否已經啟動,如何啟動,將不再重復啟動auto started_instance = started_modules_.find(module);if (started_instance != started_modules_.end()) {return started_instance->second;}// 創建一個 module 實體Module* instance = module->ctor_();LOG_INFO("Starting of %s", instance->ToString().c_str());last_instance_ = "starting " + instance->ToString();// 將 當前 module 實體和 gd_stack_thread 線程綁定set_registry_and_handler(instance, thread);LOG_INFO("Starting dependencies of %s", instance->ToString().c_str());auto start_time = std::chrono::steady_clock::now();// 如果當前啟動的 module 內部還依賴 其他很多module 將,他們都加入到 實體自己的 dependencies_ 依賴中,instance->ListDependencies(&instance->dependencies_);// 先啟動 當前module 所依賴的 module. 同時將 gd_stack_thread 傳入Start(&instance->dependencies_, thread);LOG_INFO("Finished starting dependencies and calling Start() of %s", instance->ToString().c_str());auto end_time = std::chrono::steady_clock::now();auto elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();LOG_INFO("handle_start_up: Module initialization took %lld ms", elapsed_time);// 當 前module 所依賴的所有 module 都啟動完畢后, 在調用自己的 Start() 函數來啟動自己。instance->Start();start_order_.push_back(module);// 將啟動的 module 實體加入到 started_modules_ 中, 為了避免重啟啟動。started_modules_[module] = instance;LOG_INFO("Started %s", instance->ToString().c_str());return instance;
}
- 下面是 logcat 中的日志截取, 可以看到我們實際加載了這么多模塊。
Starting of BluetoothCounterMetrics
Starting of Storage Module
Starting of BluetoothCounterMetrics
Starting of HciHalHidl
Starting of SnoopLogger
Starting of Btaa Module
Starting of Hci Layer
Starting of Storage Module
Starting of shim::Dumpsys
Starting of Vendor Specific Event Manager
Starting of Controller
Starting of Acl Manager
Starting of Le Advertising Manager
Starting of Le Scanning Manager
我們暫時先分析到這里, 會在 后面的文章中, 分別拿 HciHalHidl 和 Hci Layer 這兩個模塊 具體分析。我們先梳理啟動一個 module 都要執行那幾步:
-
創建module 實體
- Module* instance = module->ctor_();
-
將 當前 module 實體和 gd_stack_thread 線程綁定
- set_registry_and_handler(instance, thread);
-
啟動當前模塊所依賴的所有子模塊。
- instance->ListDependencies(&instance->dependencies_);
- Start(&instance->dependencies_, thread);
-
最后調用自己的 Start() 函數
- instance->Start();
-
將module 實體加入到 started_modules_
- started_modules_[module] = instance;
這里我們倆重點關注一下, 每一個 module 實體如何 和 gd_stack_thread 線程綁定的。
void ModuleRegistry::set_registry_and_handler(Module* instance, Thread* thread) const {instance->registry_ = this;instance->handler_ = new Handler(thread);
}
- 將我們的 gd_stack_thread 對應的 handle 直接保存在 Module->handler_ 中。
4. GeneralShutDown
// system/main/shim/shim.cc
future_t* GeneralShutDown() {bluetooth::shim::Stack::GetInstance()->Stop();return kReturnImmediate;
}
void Stack::Stop() {// First remove pid file so clients no stack is going downRemovePidFile();if (common::init_flags::gd_rust_is_enabled()) {if (rust_stack_ != nullptr) {rust::stack_stop(**rust_stack_);}return;}std::lock_guard<std::recursive_mutex> lock(mutex_);if (!common::init_flags::gd_core_is_enabled()) {bluetooth::shim::hci_on_shutting_down();}// Make sure gd acl flag is enabled and we started it upif (acl_ != nullptr) {acl_->FinalShutdown();delete acl_;acl_ = nullptr;}ASSERT_LOG(is_running_, "%s Gd stack not running", __func__);is_running_ = false;delete btm_;btm_ = nullptr;stack_handler_->Clear();stack_manager_.ShutDown();delete stack_handler_;stack_handler_ = nullptr;stack_thread_->Stop();delete stack_thread_;stack_thread_ = nullptr;LOG_INFO("%s Successfully shut down Gd stack", __func__);
}
這里看到 gd_shim_module 在結束的時候, 也是一樣直接調用了 Stack::Stop , 這里不再繼續展開分析了。