audio hal hidl通信
Hal audio
-
第一步AudioFlinger (audioserver进程)
eg: AudioFlinger::PatchPanel::createAudioPatch
frameworks/av/services/audioflinger/PatchPanel.cpp
/system/lib/ibaudioflinger.so -
第二步libaudiohal(audioserver进程)
eg: DeviceHalHidl::createAudioPatch
Android P:
frameworks/av/media/libaudiohal/4.0/DeviceHalHidl.cpp
/system/lib/libaudiohal@4.0.so
Android Q:
frameworks/av/media/libaudiohal/impl/DeviceHalHidl.cpp
/system/lib/libaudiohal@5.0.so -
第三步device impl (android.hardware.audio.service-droidlogic进程)
eg: Device::createAudioPatch
Android P:
hardware/interfaces/audio/core/all-versions/default/include/core/all-versions/default/Device.impl.h
/vendor/lib/hw/android.hardware.audio@4.0-impl.so
Android Q:
hardware/interfaces/audio/core/all-versions/default/Device.cpp
/vendor/lib/hw/android.hardware.audio@5.0-impl.so -
第四步 audio hal (android.hardware.audio.service-droidlogic进程)
eg: audio_hw.c create_audio_patch
/vendor/lib/hw/audio.primary.xxx.so
系统上下文
audioserver和android.hardware.audio.service-droidlogic两个进程之间调用,之间通过vndbinder通信,system分区调用vendor分区。
1. audioserver
frameworks\av\services\audioflinger\AudioFlinger.cpp
AudioFlinger::AudioFlinger()
...
{
...
// 拿去对应版本的android.hardware.audio IDevicesFactory 服务
mDevicesFactoryHal = DevicesFactoryHalInterface::create();
...
frameworks\av\media\libaudiohal\DevicesFactoryHalInterface.cpp
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
using namespace std::string_literals;
return createPreferredImpl<DevicesFactoryHalInterface>(
std::make_pair("android.hardware.audio"s, "IDevicesFactory"s),
std::make_pair("android.hardware.audio.effect"s, "IEffectsFactory"s));
}
frameworks\av\media\libaudiohal\FactoryHalHidl.cpp
bool createHalService(const std::string& version, const std::string& interface,
void** rawInterface) {
const std::string libName = "libaudiohal@" + version + ".so";
const std::string factoryFunctionName = "create" + interface;
constexpr int dlMode = RTLD_LAZY;
void* handle = nullptr;
dlerror(); // clear
ALOGI("[%s:%d] google dlopen :%s", __func__, __LINE__, libName.c_str());
// dlopen 对应版本的libaudiohal@x.so, 注:x为版本号
handle = dlopen(libName.c_str(), dlMode);
if (handle == nullptr) {
const char* error = dlerror();
ALOGE("Failed to dlopen %s: %s", libName.c_str(),
error != nullptr ? error : "unknown error");
return false;
}
void* (*factoryFunction)();
// 获取指定版本libaudiohal@x.so中的createIDevicesFactory函数地址
*(void **)(&factoryFunction) = dlsym(handle, factoryFunctionName.c_str());
if (!factoryFunction) {
const char* error = dlerror();
ALOGE("Factory function %s not found in library %s: %s",
factoryFunctionName.c_str(), libName.c_str(),
error != nullptr ? error : "unknown error");
dlclose(handle);
return false;
}
// 返回createIDevicesFactory函数地址
*rawInterface = (*factoryFunction)();
ALOGW_IF(!*rawInterface, "Factory function %s from %s returned nullptr",
factoryFunctionName.c_str(), libName.c_str());
return true;
}
bool hasHalService(const std::string& package, const std::string& version,
const std::string& interface) {
using ::android::hidl::manager::V1_0::IServiceManager;
sp<IServiceManager> sm = ::android::hardware::defaultServiceManager();
if (!sm) {
ALOGE("Failed to obtain HIDL ServiceManager");
return false;
}
// Since audio HAL doesn't support multiple clients, avoid instantiating
// the interface right away. Instead, query the transport type for it.
using ::android::hardware::Return;
using Transport = IServiceManager::Transport;
const std::string fqName = package + "@" + version + "::" + interface;
const std::string instance = "default";
// 检测指定版本的service是否存在
Return<Transport> transport = sm->getTransport(fqName, instance);
if (!transport.isOk()) {
ALOGE("Failed to obtain transport type for %s/%s: %s",
fqName.c_str(), instance.c_str(), transport.description().c_str());
return false;
}
ALOGI("[%s:%d] google transport:%d, package:%s", __func__, __LINE__, transport != Transport::EMPTY, fqName.c_str());
return transport != Transport::EMPTY;
}
void* createPreferredImpl(const InterfaceName& iface, const InterfaceName& siblingIface) {
auto findMostRecentVersion = [](const InterfaceName& iface) {
// 根据sAudioHALVersions中定义的audio 版本进行分别遍历各个版本的service是否存在,从高版本开始遍历。
return std::find_if(detail::sAudioHALVersions.begin(), detail::sAudioHALVersions.end(),
[&](const auto& v) { return hasHalService(iface.first, v.second, iface.second); });
};
ALOGI("[%s:%d] google createPreferredImpl begin+++++", __func__, __LINE__);
auto ifaceVersionIt = findMostRecentVersion(iface);
ALOGI("[%s:%d] google ", __func__, __LINE__);
auto siblingVersionIt = findMostRecentVersion(siblingIface);
if (ifaceVersionIt != detail::sAudioHALVersions.end() &&
siblingVersionIt != detail::sAudioHALVersions.end() &&
// same major version
ifaceVersionIt->first.first == siblingVersionIt->first.first) {
// 优先使用android.hardware.audio的Major版本的service,android.hardware.audio.effect跟随
std::string libraryVersion =
ifaceVersionIt->first >= siblingVersionIt->first ?
ifaceVersionIt->second : siblingVersionIt->second;
void* rawInterface;
ALOGI("[%s:%d] google Interface:%s, version:%s", __func__, __LINE__, iface.second.c_str(), libraryVersion.c_str());
if (createHalService(libraryVersion, iface.second, &rawInterface)) {
ALOGI("[%s:%d] google createHalService Interface:%s, version:%s",
__func__, __LINE__, iface.second.c_str(), libraryVersion.c_str());
return rawInterface;
}
}
return nullptr;
}
646 646 I FactoryHalHidl: [createPreferredImpl:109] google createPreferredImpl begin+++++
646 646 I FactoryHalHidl: [hasHalService:98] google transport:1, package:android.hardware.audio@7.1::IDevicesFactory
646 646 I FactoryHalHidl: [createPreferredImpl:111] google
646 646 I FactoryHalHidl: [hasHalService:98] google transport:0, package:android.hardware.audio.effect@7.1::IEffectsFactory
646 646 I FactoryHalHidl: [hasHalService:98] google transport:1, package:android.hardware.audio.effect@7.0::IEffectsFactory
646 646 I FactoryHalHidl: [createPreferredImpl:121] google Interface:IDevicesFactory, version:7.1
646 646 I FactoryHalHidl: [createHalService:54] google dlopen :libaudiohal@7.1.so
646 646 I FactoryHalHidl: [createPreferredImpl:124] google createHalService Interface:IDevicesFactory, version:7.1
frameworks\av\media\libaudiohal\impl\DevicesFactoryHalHidl.cpp
// Main entry-point to the shared library.
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
return service ? new DevicesFactoryHalHidl(service) : nullptr;
}
DevicesFactoryHalHidl.cpp被编译到各个版本的libaudiohal@x.so当中
2. android.hardware.audio.service
hardware/interfaces/audio/common/all-versions/default/service/service.cpp
不同的版本实现
hardware\interfaces\audio\core\all-versions\default\DevicesFactory.cpp
DevicesFactory.cpp被编译到各个版本的android.hardware.audio@x-impl当中
audio hal的 adev_open返回的hw_device_t / audio_hw_device指针变量的地址也在PrimaryDevice实例中管理
template <class DeviceShim, class Callback>
Return<void> DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
ALOGI("[%s:%d] this:%p MAJOR_VERSION:%d MINOR_VERSION:%d moduleName:%s", __func__, __LINE__, this, MAJOR_VERSION, MINOR_VERSION, moduleName);
audio_hw_device_t* halDevice;
Result retval(Result::INVALID_ARGUMENTS);
sp<DeviceShim> result;
int halStatus = loadAudioInterface(moduleName, &halDevice);
if (halStatus == OK) {
result = new DeviceShim(halDevice);
retval = Result::OK;
} else if (halStatus == -EINVAL) {
retval = Result::NOT_INITIALIZED;
}
_hidl_cb(retval, result);
return Void();
}
// static
int DevicesFactory::loadAudioInterface(const char* if_name, audio_hw_device_t** dev) {
ALOGI("[%s:%d] MAJOR_VERSION:%d MINOR_VERSION:%d if_name:%s", __func__, __LINE__, MAJOR_VERSION, MINOR_VERSION, if_name);
const hw_module_t* mod;
int rc;
rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
if (rc) {
ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
if_name, strerror(-rc));
goto out;
}
rc = audio_hw_device_open(mod, dev);
ALOGI("[%s:%d] name:%s, adev:%p", __func__, __LINE__, if_name, *dev);
if (rc) {
ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
if_name, strerror(-rc));
goto out;
}
if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
rc = -EINVAL;
audio_hw_device_close(*dev);
goto out;
}
return OK;
out:
*dev = NULL;
return rc;
}