【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 层
  }
相关推荐
千里马学框架21 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台21 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077001 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone1 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen1 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone1 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui