Audio HAL(Hardware Abstraction Layer)是 Android 音频系统和底层音频驱动之间的桥梁,负责提供统一的接口,让 AudioFlinger(音频框架)可以与不同的音频硬件通信。它位于 Android 音频架构的 Framework 层 和 驱动层 之间。
vendor.audio-hal 服务启动
以车载模拟器代码为例
系统启动时 init 进程会启动 vendor.audio-hal 服务
kotlin
service vendor.audio-hal /vendor/bin/hw/android.hardware.audio.service-caremu
override
class hal
user audioserver
# media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
capabilities BLOCK_SUSPEND
ioprio rt 4
task_profiles ProcessCapacityHigh HighPerformance
/vendor/bin/hw/android.hardware.audio.service-caremu 源代码
这个程序的功能主要是
- 注册 2 个 HIDL 服务到 hwservicemanger
IDevicesFactory
创建音频输入输出设备接口IEffectsFactory
音频效果处理接口
- 注册 1 个 aidl 接口到 servicemangaer
AudioControl
车载音频控制
cpp
int main(int /* argc */, char* /* argv */ []) {
// Setup HIDL Audio HAL
LOG(INFO) << "AudioControl start audio HAL.";
// 配置 HIDL 线程池最大线程数
configureRpcThreadpool(16, false /*callerWillJoin*/);
android::status_t status;
// 注册 IDevicesFactory HIDL 接口
status = registerPassthroughServiceImplementation<IDevicesFactory>();
LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio service: %d", status);
// 注册 IEffectsFactory HIDL 接口
status = registerPassthroughServiceImplementation<IEffectsFactory>();
LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio effects service: %d", status);
// 设置 aidl 线程池最大线程数
ABinderProcess_setThreadPoolMaxThreadCount(16);
std::shared_ptr<AudioControl> audioControl = ::ndk::SharedRefBase::make<AudioControl>();
const std::string instance = std::string() + AudioControl::descriptor + "/default";
// 把 AudioControl 添加到 binder 系统服务中
binder_status_t aidlStatus = AServiceManager_addService(audioControl->asBinder().get(),
instance.c_str());
CHECK(aidlStatus == STATUS_OK);
LOG(INFO) << "AudioControl status: status " << aidlStatus;
// 进入binder线程池循环,等待 binder 内核发出来的消息
ABinderProcess_joinThreadPool();
LOG(ERROR) << "ABinderProcess_joinThreadPool should never get here ";
return EXIT_FAILURE; // should not reach
}
IDevicesFactory 注册到 hwservicemanager
cpp
// Interface 和 ExpectInterface 都是 IDevicesFactory
template <class Interface, class ExpectInterface = Interface>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
const std::string& name = "default") {
return registerPassthroughServiceImplementation(Interface::descriptor,
ExpectInterface::descriptor, name);
}
// interfaceName : [email protected]::IDevicesFactory
// expectInterfaceName : [email protected]::IDevicesFactory
// serviceName : default
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
const std::string& interfaceName, const std::string& expectInterfaceName,
const std::string& serviceName) {
return details::registerPassthroughServiceImplementation(
interfaceName, expectInterfaceName,
// RegisterServiceCb ,lambda 表示式
[](const sp<IBase>& service, const std::string& name) {
// service 为 DevicesFactory ,name 为 default
return details::registerAsServiceInternal(service, name);
},
serviceName);
}
using RegisterServiceCb =
std::function<status_t(const sp<::android::hidl::base::V1_0::IBase>&, const std::string&)>;
// interfaceName : [email protected]::IDevicesFactory
// expectInterfaceName : [email protected]::IDevicesFactory
// registerServiceCb : lambda 表示式 callback
// serviceName : default
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
const std::string& interfaceName, const std::string& expectInterfaceName,
RegisterServiceCb registerServiceCb, const std::string& serviceName) {
// 调用 getRawServiceInternal 获取 sp<IBase>
sp<IBase> service =
getRawServiceInternal(interfaceName, serviceName, true /*retry*/, true /*getStub*/);
// 回调 registerServiceCb
status_t status = registerServiceCb(service, serviceName);
if (status == OK) {
ALOGI("Registration complete for %s/%s.", interfaceName.c_str(), serviceName.c_str());
} else {
ALOGE("Could not register service %s/%s (%d).", interfaceName.c_str(), serviceName.c_str(),
status);
}
return status;
}
// service 为 DevicesFactory ,name 为 default
status_t registerAsServiceInternal(const sp<IBase>& service, const std::string& name) {
if (service == nullptr) {
return UNEXPECTED_NULL;
}
// 获取 hwservicemanager
sp<IServiceManager1_2> sm = defaultServiceManager1_2();
if (sm == nullptr) {
return INVALID_OPERATION;
}
const std::string descriptor = getDescriptor(service.get());
if (kEnforceVintfManifest && !isTrebleTestingOverride()) {
using Transport = IServiceManager1_0::Transport;
Return<Transport> transport = sm->getTransport(descriptor, name);
if (!transport.isOk()) {
LOG(ERROR) << "Could not get transport for " << descriptor << "/" << name << ": "
<< transport.description();
return UNKNOWN_ERROR;
}
if (transport != Transport::HWBINDER) {
LOG(ERROR) << "Service " << descriptor << "/" << name
<< " must be in VINTF manifest in order to register/get.";
return UNKNOWN_ERROR;
}
}
bool registered = false;
Return<void> ret = service->interfaceChain([&](const auto& chain) {
// 把 DevicesFactory 添加到 hwservicemanager
registered = sm->addWithChain(name.c_str(), service, chain).withDefault(false);
});
if (!ret.isOk()) {
LOG(ERROR) << "Could not retrieve interface chain: " << ret.description();
}
if (registered) {
onRegistrationImpl(descriptor, name);
}
return registered ? OK : UNKNOWN_ERROR;
}
cpp
// descriptor : [email protected]::IDevicesFactory
// instance : default
// retry : true
// getStub : true
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance, bool retry, bool getStub) {
using Transport = IServiceManager1_0::Transport;
sp<IServiceManager1_1> sm;
Transport transport = Transport::EMPTY;
if (kIsRecovery) {
transport = Transport::PASSTHROUGH;
} else {
// 获取 hwservicemanager
sm = defaultServiceManager1_1();
if (sm == nullptr) {
ALOGE("getService: defaultServiceManager() is null");
return nullptr;
}
Return<Transport> transportRet = sm->getTransport(descriptor, instance);
if (!transportRet.isOk()) {
ALOGE("getService: defaultServiceManager()->getTransport returns %s",
transportRet.description().c_str());
return nullptr;
}
transport = transportRet;
}
const bool vintfHwbinder = (transport == Transport::HWBINDER);
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
const bool trebleTestingOverride = isTrebleTestingOverride();
const bool allowLegacy = !kEnforceVintfManifest || (trebleTestingOverride && isDebuggable());
const bool vintfLegacy = (transport == Transport::EMPTY) && allowLegacy;
// getStub 为 true
if (getStub || vintfPassthru || vintfLegacy) {
// 获取 HIDL 直通(Passthrough)服务管理者
const sp<IServiceManager1_0> pm = getPassthroughServiceManager();
if (pm != nullptr) {
// 调用 get 方法
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}
return nullptr;
}
sp<IServiceManager1_0> getPassthroughServiceManager() {
return getPassthroughServiceManager1_1();
}
sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
return manager;
}
struct PassthroughServiceManager : IServiceManager1_1 {
// fqName : [email protected]::IDevicesFactory
// name : default
Return<sp<IBase>> get(const hidl_string& fqName,
const hidl_string& name) override {
sp<IBase> ret = nullptr;
// 调用 openLibs 加载 so
// handle : 动态库的句柄(`void*` 指针)
// lib : [email protected]
// sym : HIDL_FETCH_IDevicesFactory
openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
// 定义函数指针
IBase* (*generator)(const char* name);
// 从 so 里面加载 HIDL_FETCH_IDevicesFactory 方法
*(void **)(&generator) = dlsym(handle, sym.c_str());
if(!generator) {
const char* error = dlerror();
LOG(ERROR) << "Passthrough lookup opened " << lib << " but could not find symbol "
<< sym << ": " << (error == nullptr ? "unknown error" : error)
<< ". Keeping library open.";
return true; // continue
}
// 调用 generator( HIDL_FETCH_IDevicesFactory )函数
ret = (*generator)(name.c_str());
if (ret == nullptr) {
LOG(ERROR) << "Could not find instance '" << name.c_str() << "' in library " << lib
<< ". Keeping library open.";
return true; // continue
}
using ::android::hardware::details::getDescriptor;
std::string actualFqName = getDescriptor(ret.get());
CHECK(actualFqName.size() > 0);
registerReference(actualFqName, name);
return false;
});
LOG(DEBUG) << "get name : " << (ret== nullptr);
return ret;
}
// fqName : [email protected]::IDevicesFactory
static void openLibs(
const std::string& fqName,
const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
const std::string& /* sym */)>& eachLib) {
// fqName : [email protected]::IDevicesFactory
size_t idx = fqName.find("::");
// [email protected]
std::string packageAndVersion = fqName.substr(0, idx);
// IDevicesFactory
std::string ifaceName = fqName.substr(idx + strlen("::"));
// [email protected]
const std::string prefix = packageAndVersion + "-impl";
// HIDL_FETCH_IDevicesFactory
const std::string sym = "HIDL_FETCH_" + ifaceName;
constexpr int dlMode = RTLD_LAZY;
void* handle = nullptr;
dlerror(); // clear
static std::string halLibPathVndkSp = details::getVndkSpHwPath();
// 指定搜索路径
std::vector<std::string> paths = {
HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, halLibPathVndkSp,
#ifndef __ANDROID_VNDK__
HAL_LIBRARY_PATH_SYSTEM,
#endif
};
for (const std::string& path : paths) {
std::vector<std::string> libs = findFiles(path, prefix, ".so");
for (const std::string &lib : libs) {
// fullPath : /vendor/lib64/hw/[email protected]
const std::string fullPath = path + lib;
if (kIsRecovery || path == HAL_LIBRARY_PATH_SYSTEM) {
handle = dlopen(fullPath.c_str(), dlMode);
} else {
#if !defined(__ANDROID_RECOVERY__) && defined(__ANDROID__)
// 加载 /vendor/lib64/hw/[email protected]
handle = android_load_sphal_library(fullPath.c_str(), dlMode);
#endif
}
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen " << lib << ": "
<< (error == nullptr ? "unknown error" : error);
continue;
}
// 调用 eachLib 函数
if (!eachLib(handle, lib, sym)) {
return;
}
}
}
}
// 注册到 hwservicemanager ,做个统计调试用
// interfaceName : [email protected]::IDevicesFactory
// instanceName : default
fqName [email protected]::IDevicesFactory name default
static void registerReference(const hidl_string &interfaceName, const hidl_string &instanceName) {
sp<IServiceManager1_0> binderizedManager = defaultServiceManager();
auto ret = binderizedManager->registerPassthroughClient(interfaceName, instanceName);
LOG(VERBOSE) << "Successfully registerReference for "
<< interfaceName << "/" << instanceName;
}
android.bp 编译
cpp
cc_defaults {
name: "[email protected]_default",
defaults: ["android.hardware.audio-impl_default"],
shared_libs: [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
],
cflags: [
"-DMAJOR_VERSION=6",
"-DMINOR_VERSION=0",
"-include common/all-versions/VersionMacro.h",
],
}
cc_library_shared {
name: "[email protected]",
defaults: ["[email protected]_default"],
}
cpp
namespace android {
namespace hardware {
namespace audio {
namespace CPP_VERSION {
namespace implementation {
using ::android::sp;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using namespace ::android::hardware::audio::CPP_VERSION;
struct DevicesFactory : public IDevicesFactory {
#if MAJOR_VERSION == 2
Return<void> openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) override;
#elif MAJOR_VERSION >= 4
Return<void> openDevice(const hidl_string& device, openDevice_cb _hidl_cb) override;
Return<void> openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override;
#endif
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
Return<void> openDevice_7_1(const hidl_string& device, openDevice_7_1_cb _hidl_cb) override;
Return<void> openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) override;
#endif
private:
template <class DeviceShim, class Callback>
Return<void> openDevice(const char* moduleName, Callback _hidl_cb);
#if MAJOR_VERSION == 2
Return<void> openDevice(const char* moduleName, openDevice_cb _hidl_cb);
#endif
static int loadAudioInterface(const char* if_name, audio_hw_device_t** dev);
};
extern "C" IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name);
}
// 创建 DevicesFactory 对象
IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name) {
return strcmp(name, "default") == 0 ? new DevicesFactory() : nullptr;
}
IEffectsFactory 的注册和 IDevicesFactory 类似,不赘述
这里只介绍 IDevicesFactory 和 IEffectsFactory 注册到 hwservicemanager 过程。这两个接口的使用在后面 audioserver 介绍