【android bluetooth 框架分析 02】【Module详解 3】【HciHal 模块介绍】

1. 背景

我们在 gd_shim_module 介绍章节中,看到 我们将 HciHal 模块加入到了 modules 中。

c 复制代码
modules.add<hal::HciHal>();

在 ModuleRegistry::Start 函数中我们对 加入的所有 module 挨个初始化。

而在该函数中启动一个 module 都要执行那下面几步:

  1. 创建module 实体

    • Module* instance = module->ctor_();
  2. 将 当前 module 实体和 gd_stack_thread 线程绑定

    • set_registry_and_handler(instance, thread);
  3. 启动当前模块所依赖的所有子模块。

    • instance->ListDependencies(&instance->dependencies_);
    • Start(&instance->dependencies_, thread);
  4. 最后调用自己的 Start() 函数

    • instance->Start();
  5. 将module 实体加入到 started_modules_

    • started_modules_[module] = instance;

本篇文章就拿 hal::HciHal 模块来具体分析一下 他的启动。

2. modules.add

我们先来看一下 在调用 modules.add 时, 到底做了那些事情。

c 复制代码
modules.add<hal::HciHal>();
c 复制代码
class ModuleList {
 friend Module;
 friend ModuleRegistry;

public:
 template <class T>
 void add() {
   list_.push_back(&T::Factory); // add 时 添加的是 hal::HciHal::Factory
 }

 private:
  std::vector<const ModuleFactory*> list_;
};
  • 从代码中不难发现, 我们是将 hal::HciHal::Factory 加入到 list_ 中的。
c 复制代码
// system/gd/hal/hci_hal_android_hidl.cc
const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHidl(); }); // 这里在创建 ModuleFactory 对象时, 传入了一个 函数, 这个函数 去 new HciHalHidl 对象
  • 这里在创建 ModuleFactory 对象时, 传入了一个 函数,但是并没有去调用这个函数。
    • 这个函数的目的是 去 new HciHalHidl 对象
c 复制代码
class ModuleFactory {
 friend ModuleRegistry;
 friend FuzzTestModuleRegistry;

public:
 ModuleFactory(std::function<Module*()> ctor);

private:
 std::function<Module*()> ctor_;
};

//  system/gd/module.cc
ModuleFactory::ModuleFactory(std::function<Module*()> ctor) : ctor_(ctor) {
}
  • 在创建 ModuleFactory 对象时, 也仅仅是将 如下的函数赋值给了 ModuleFactory::ctor_ 函数指针。
c 复制代码
[]() { 
	return new HciHalHidl(); 

}

3. 模块具体启动流程

1. 创建module 实体

  1. 创建module 实体
    • Module* instance = module->ctor_();
c 复制代码
[]() { 
	return new HciHalHidl(); 

}
  • 这里就会去实际触发 该函数,去创建 HciHalHidl 对象。
  • 也就是说, modules.addhal::HciHal() 模块对应的 实体其实是 HciHalHidl对象。
c 复制代码
class HciHalHidl : public HciHal {

}
  • HciHalHidl 继承 HciHal
c 复制代码
class HciHal : public ::bluetooth::Module {

}
  • HciHal 又继承 Module

2. 将 当前 module 实体和 gd_stack_thread 线程绑定

  1. 将 当前 module 实体和 gd_stack_thread 线程绑定
    • set_registry_and_handler(instance, thread);
c 复制代码
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_ 中。
c 复制代码
Handler* Module::GetHandler() const {
  ASSERT_LOG(handler_ != nullptr, "Can't get handler when it's not started");
  return handler_;
}
  • 通过 Module::GetHandler() 来获取当前 handler_

3.启动当前模块所依赖的所有子模块

  1. 启动当前模块所依赖的所有子模块。
    • instance->ListDependencies(&instance->dependencies_);
    • Start(&instance->dependencies_, thread);
c 复制代码
// system/gd/hal/hci_hal_android_hidl.cc
  void ListDependencies(ModuleList* list) const {
    list->add<SnoopLogger>();
    if (common::init_flags::btaa_hci_is_enabled()) {
      list->add<activity_attribution::ActivityAttribution>();
    }
  }
  • 这里调用了 HciHalHidl对象的ListDependencies , 他只依赖SnoopLogger 模块

Start(&instance->dependencies_, thread);

  • 这里会先去启动 SnoopLogger 模块

4. 最后调用自己的 Start() 函数

  1. 最后调用自己的 Start() 函数
    • instance->Start();
c 复制代码
  // system/gd/hal/hci_hal_android_hidl.cc
  
  void Start() override {
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_ = GetDependency<activity_attribution::ActivityAttribution>();
    }
    btsnoop_logger_ = GetDependency<SnoopLogger>();
    LOG_INFO("GetService start.");

    // 这里 创建一个定时器, 此时将 gd_stack_thread 对应的 handle 传递给 了定时器
    auto get_service_alarm = new os::Alarm(GetHandler());

    // 定时器定时 1s, 如果超时,将跑在 gd_stack_thread 线程中
    get_service_alarm->Schedule(
        BindOnce([] {
          LOG_ALWAYS_FATAL("Unable to get a Bluetooth service after 500ms, start the HAL before starting Bluetooth");
        }),
        std::chrono::milliseconds(1000));


   // 向 SM 获取 IBluetoothHci_1_0 服务。
    std::string instance = GetHciInstance();

    bt_hci_1_1_ = IBluetoothHci::getService(instance);

    if (bt_hci_1_1_ != nullptr) {
      bt_hci_ = bt_hci_1_1_;
    } else {
      bt_hci_ = IBluetoothHci_1_0::getService(instance);
    }

    // 如果成功 向 SM获取hidl 服务, 就取消 之前的定时器,否则,1s超时后,报错,无法访问到 hidl 服务。
    get_service_alarm->Cancel();
    delete get_service_alarm;

    LOG_INFO("GetService Done.");


    // 向 蓝牙 hal 进程注册死亡回调
    ASSERT(bt_hci_ != nullptr);
    auto death_link = bt_hci_->linkToDeath(hci_death_recipient_, 0);
    ASSERT_LOG(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL");
    callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会掉我们的 接口

    if (bt_hci_1_1_ != nullptr) {
      bt_hci_1_1_->initialize_1_1(callbacks_);
    } else {
      // 掉hal 接口, 触发 hal 初始化,将回调接口告知 hal进程。
      bt_hci_->initialize(callbacks_);
    }

    // Don't timeout here, time out at a higher layer
    callbacks_->GetInitPromise()->get_future().wait();
  }
  • callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会掉我们的 接口

1. InternalHciCallbacks

我们来看一下, 我们向 hal 进程, 注册的回调 长啥样子。

c 复制代码
class InternalHciCallbacks : public IBluetoothHciCallbacks {


}
  • InternalHciCallbacks 继承 IBluetoothHciCallbacks 接口。
c 复制代码
class InternalHciCallbacks : public IBluetoothHciCallbacks {
 public:
  InternalHciCallbacks(activity_attribution::ActivityAttribution* btaa_logger_, SnoopLogger* btsnoop_logger)
      : btaa_logger_(btaa_logger_), btsnoop_logger_(btsnoop_logger) {
    init_promise_ = new std::promise<void>();
  }

  void SetCallback(HciHalCallbacks* callback) {
    ASSERT(callback_ == nullptr && callback != nullptr);
    callback_ = callback;
  }

  void ResetCallback() {
    callback_ = nullptr;
  }

  std::promise<void>* GetInitPromise() {
    return init_promise_;
  }

  // 当 hal 初始化完后,会调用它,通知我们
  Return<void> initializationComplete(HidlStatus status) {
    common::StopWatch stop_watch(__func__);
    ASSERT(status == HidlStatus::SUCCESS);
    init_promise_->set_value();
    return Void();
  }


  // 当 收到 hci event 后, 会回调我们
  Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) override {
    common::StopWatch stop_watch(GetTimerText(__func__, event));
    std::vector<uint8_t> received_hci_packet(event.begin(), event.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::EVT);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::EVT);
    }
    if (callback_ != nullptr) {
      callback_->hciEventReceived(std::move(received_hci_packet));
    }
    return Void();
  }


 // 当收到  acl 数据后,会回调我们
  Return<void> aclDataReceived(const hidl_vec<uint8_t>& data) override {
    common::StopWatch stop_watch(GetTimerText(__func__, data));
    std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::ACL);
    }
    if (callback_ != nullptr) {
      callback_->aclDataReceived(std::move(received_hci_packet));
    }
    return Void();
  }


  // 当收到 sco 语音数据,会回调给我们
  Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) override {
    common::StopWatch stop_watch(GetTimerText(__func__, data));
    std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::SCO);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::SCO);
    }
    if (callback_ != nullptr) {
      callback_->scoDataReceived(std::move(received_hci_packet));
    }
    return Void();
  }


  // 当收到 leaudio 数据 会回调我们
  Return<void> isoDataReceived(const hidl_vec<uint8_t>& data) override {
    common::StopWatch stop_watch(GetTimerText(__func__, data));
    std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ISO);
    if (callback_ != nullptr) {
      callback_->isoDataReceived(std::move(received_hci_packet));
    }
    return Void();
  }

 private:
  std::promise<void>* init_promise_ = nullptr;
  HciHalCallbacks* callback_ = nullptr;
  activity_attribution::ActivityAttribution* btaa_logger_ = nullptr;
  SnoopLogger* btsnoop_logger_ = nullptr;
};

5.将module 实体加入到 started_modules_

  1. 将module 实体加入到 started_modules_
    • started_modules_[module] = instance;

4. HciHalHidl 模块其他接口介绍

c 复制代码
// system/gd/hal/hci_hal_android_hidl.cc
class HciHalHidl : public HciHal {


public:
  void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
    callbacks_->SetCallback(callback);
  }

  void unregisterIncomingPacketCallback() override {
    callbacks_->ResetCallback();
  }

  void sendHciCommand(HciPacket command) override {
    btsnoop_logger_->Capture(command, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(command, SnoopLogger::PacketType::CMD);
    }
    bt_hci_->sendHciCommand(command);
  }

  void sendAclData(HciPacket packet) override {
    btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(packet, SnoopLogger::PacketType::ACL);
    }
    bt_hci_->sendAclData(packet);
  }

  void sendScoData(HciPacket packet) override {
    btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::SCO);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(packet, SnoopLogger::PacketType::SCO);
    }
    bt_hci_->sendScoData(packet);
  }

  void sendIsoData(HciPacket packet) override {
    if (bt_hci_1_1_ == nullptr) {
      LOG_ERROR("ISO is not supported in HAL v1.0");
      return;
    }

    btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ISO);
    bt_hci_1_1_->sendIsoData(packet);
  }
}

1.registerIncomingPacketCallback

c 复制代码
  void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
    callbacks_->SetCallback(callback);
  }
  • 在之前分析 instance->Start(); 调用时有如下代码
    • callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会掉我们的 接口
    • bt_hci_->initialize(callbacks_); 将 InternalHciCallbacks 注册进 hal 进程

当 hal 进程中有 hci event 上报时, 先调用到 InternalHciCallbacks 的hciEventReceived, 从而触发 callback_->hciEventReceived(std::move(received_hci_packet));

而这里的 callback_ 就是通过 registerIncomingPacketCallback 调用 callbacks_->SetCallback(callback); 注册进来的。

c 复制代码
  // system/gd/hal/hci_hal_android_hidl.cc
  void SetCallback(HciHalCallbacks* callback) {
    ASSERT(callback_ == nullptr && callback != nullptr);
    callback_ = callback;
  }
c 复制代码
  // 当 收到 hci event 后, 会回调我们
  Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) override {
    common::StopWatch stop_watch(GetTimerText(__func__, event));
    std::vector<uint8_t> received_hci_packet(event.begin(), event.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::EVT);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::EVT);
    }
    if (callback_ != nullptr) {
      callback_->hciEventReceived(std::move(received_hci_packet)); // 继续调用 hciEventReceived
    }
    return Void();
  }

那是谁调用的 registerIncomingPacketCallback

c 复制代码
// system/gd/hci/hci_layer.cc
void HciLayer::Start() {

	hal_callbacks_ = new hal_callbacks(*this);

	hal->registerIncomingPacketCallback(hal_callbacks_);

}
  • 是在初始化 HciLayer 模块的 Start 函数中调用的。本机只分析 HciHal模块, HciLayer 模块在其他文章中分析。 这里不再展开分析。 只做记录。
c 复制代码
// system/gd/hci/hci_layer.cc
struct HciLayer::hal_callbacks : public hal::HciHalCallbacks {
  hal_callbacks(HciLayer& module) : module_(module) {}

  void hciEventReceived(hal::HciPacket event_bytes) override {
    auto packet = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(event_bytes));
    EventView event = EventView::Create(packet);


	// 这里之前, 都是在Binder 线程池中执行的, 应为涉及到 跨进程间通信
	// 调用 module_.CallOn 将从 Binder线程, 的任务抛给 模块的线程处理, 这里就是  gd_stack_thread 线程
    module_.CallOn(module_.impl_, &impl::on_hci_event, move(event));
  }
};
c 复制代码
// system/gd/module.h
  void CallOn(T* obj, Functor&& functor, Args&&... args) {
    GetHandler()->CallOn(obj, std::forward<Functor>(functor), std::forward<Args>(args)...);
  }
  • GetHandler() 返回的就是 gd_stack_thread 线程 对应的 handler

所以 最终 hal进程的回调, 先调用到 HciHal 模块的 callback , 最终在调用到 HciLayer::hal_callbacks。 这样逐级向上调用。

2. sendHciCommand

c 复制代码
// system/gd/hci/hci_layer.cc
void send_next_command() {
	hal_->sendHciCommand(*bytes);
}


// system/gd/hal/hci_hal_android_hidl.cc
void sendHciCommand(HciPacket command) override {
    btsnoop_logger_->Capture(command, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(command, SnoopLogger::PacketType::CMD);
    }
    bt_hci_->sendHciCommand(command);
  }
  • HciLayer::send_next_command 调用 HciHalHidl::sendHciCommand 通过 hal 接口 发送命令给 hal 进程。

3. sendAclData

c 复制代码
  // HciLayer
  // system/gd/hci/hci_layer.cc
  void on_outbound_acl_ready() {
    auto packet = acl_queue_.GetDownEnd()->TryDequeue();
    std::vector<uint8_t> bytes;
    BitInserter bi(bytes);
    packet->Serialize(bi);
    hal_->sendAclData(bytes); // 调用 HciHalHidl 层
  }

4. sendScoData

c 复制代码
  // HciLayer
  // system/gd/hci/hci_layer.cc
  void on_outbound_sco_ready() {
    auto packet = sco_queue_.GetDownEnd()->TryDequeue();
    std::vector<uint8_t> bytes;
    BitInserter bi(bytes);
    packet->Serialize(bi);
    hal_->sendScoData(bytes); // 调用 HciHalHidl 层
  }

5. sendIsoData

c 复制代码
// HciLayer
// system/gd/hci/hci_layer.cc
void on_outbound_iso_ready() {
    auto packet = iso_queue_.GetDownEnd()->TryDequeue();
    std::vector<uint8_t> bytes;
    BitInserter bi(bytes);
    packet->Serialize(bi);
    hal_->sendIsoData(bytes); // 调用 HciHalHidl 层
  }
相关推荐
雨白4 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹6 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空7 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭8 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日9 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安9 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑9 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟13 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡15 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0015 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体