概述
基于AOSP SDK 28 的 audioserver 服务(内部 AudioFlinger、AudioPolicyService )以及其关联的 audio hal 服务的初始化的学习记录。
audio hal 服务初始化
1. 项目中如何找到这个服务
- adb shell ps -ef | grep audioserver 得到几个user是audioserver的进程了
- 根据进程名称就可以知道那个是audio hal服务了,如当前项目上的是:anroid.hardware.audio@2.0-serivece
- 根据信息得知这个服务是定义在rc文件中的,grep -rn "anroid.hardware.audio@2.0-serivece" . --include=*.rc 代码一般是和这个rc文件在一起
- 上面找到了服务的代码只是第一步,再然后找到具体实现,在AOSP完全编译后代码中find out/target/product/ -name "android.hardware.audio@*-impl.so" 就可以知道项目是使用的哪个版本的hal实现了,如2.0, 4.0, 5.0, 7.1这样。
2. 关联的源码
这里以audio hal 4.0 实现为例,我当前的项目也是用的4.0实现🐶
frameworks/native/libs/binder/include/binder/ProcessState.h
hardware/interfaces/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc //android p的代码这里就是2.0命名
hardware/interfaces/audio/common/all-versions/default/service/service.cpp
hardware/interfaces/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.impl.h
system/libhidl/transport/include/hidl/LegacySupport.h
system/libhidl/transport/include/hidl/HidlTransportSupport.h
system/libhidl/transport/ServiceManagement.cpp
out/soong/.intermediates/hardware/interfaces/audio/4.0/android.hardware.audio@4.0_genc++_headers/gen/android/hardware/audio/4.0/IDevicesFactory.h
out/soong/.intermediates/hardware/interfaces/audio/4.0/android.hardware.audio@4.0_genc++/gen/android/hardware/audio/4.0/DevicesFactoryAll.cpp
out/soong/.intermediates/system/libhidl/transport/manager/1.0/android.hidl.manager@1.0_genc++/gen/android/hidl/manager/1.0/ServiceManagerAll.cpp
out/soong/.intermediates/system/libhidl/transport/manager/1.1/android.hidl.manager@1.1_genc++/gen/android/hidl/manager/1.1/ServiceManagerAll.cpp
3. 初始化时序
sequenceDiagram
service.cpp ->> LegacySupport.h : registerPassthroughServiceImplementation()
LegacySupport.h ->> DevicesFactoryAll.cpp : getService()
DevicesFactoryAll.cpp ->> HidlTransportSupport.h : getServiceInternal()
HidlTransportSupport.h ->> ServiceManagement.cpp : getRawServiceInternal()
ServiceManagement.cpp -->> ServiceManagement.cpp : getPassthroughServiceManager()
ServiceManagement.cpp -->> ServiceManagement.cpp : PassthroughServiceManager::get()
ServiceManagement.cpp -->> ServiceManagement.cpp : PassthroughServiceManager::openLibs()
ServiceManagement.cpp ->> DevicesFactory.impl.h : HIDL_FETCH_IDevicesFactory()
DevicesFactory.impl.h -->> ServiceManagement.cpp : reture IDevicesFactory*
ServiceManagement.cpp -->> HidlTransportSupport.h : reture sp<IBase>
HidlTransportSupport.h -->> DevicesFactoryAll.cpp : reture sp<IDevicesFactory>
DevicesFactoryAll.cpp -->> LegacySupport.h : reture sp<IDevicesFactory>
LegacySupport.h ->> DevicesFactoryAll.cpp : registerAsService()
DevicesFactoryAll.cpp -) ServiceManagement.cpp : onRegistration()
ServiceManagement.cpp -->> ServiceManagement.cpp : tryShortenProcessName()
DevicesFactoryAll.cpp ->> ServiceManagement.cpp : defaultServiceManager()
ServiceManagement.cpp -->> ServiceManagement.cpp : defaultServiceManager1_1()
ServiceManagement.cpp -->> DevicesFactoryAll.cpp : reture sp<IServiceManager1_1>
DevicesFactoryAll.cpp ->> ServiceManagerAll.cpp : add()
ServiceManagerAll.cpp -->> DevicesFactoryAll.cpp : reture boolean
DevicesFactoryAll.cpp -->> LegacySupport.h : reture boolean
LegacySupport.h -->> service.cpp : reture boolean
4. 初始化详细
- 初始化AIL定义:
hardware/interfaces/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc
service vendor.audio-hal-2-0 /vendor/bin/hw/android.hardware.audio@2.0-service
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
ioprio rt 4
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
# audioflinger restarts itself when it loses connection with the hal
# and its .rc file has an "onrestart restart audio-hal" rule, thus
# an additional auto-restart from the init process isn't needed.
oneshot
interface android.hardware.audio@4.0::IDevicesFactory default
interface android.hardware.audio@2.0::IDevicesFactory default
这里定义了一个服务
进程名称:android.hardware.audio@2.0-service
类型:hal
所属用户:audioserver
hal类型的服务会在init.rc中定义的boot阶段被统一启动
class_start hal
- main函数
hardware/interfaces/audio/common/all-versions/default/service/service.cpp
int main(int /* argc */, char* /* argv */ []) {
//mmap binder
android::ProcessState::initWithDriver("/dev/vndbinder");
// 打开线程池保持和vndbinder通信
android::ProcessState::self()->startThreadPool();
configureRpcThreadpool(16, true /*callerWillJoin*/);
//注册直通服务,本文只有4.0是实现了
bool fail = registerPassthroughServiceImplementation<audio::V4_0::IDevicesFactory>() != OK && registerPassthroughServiceImplementation<audio::V2_0::IDevicesFactory>() != OK;
LOG_ALWAYS_FATAL_IF(fail, "Could not register audio core API 2.0 nor 4.0");
fail = registerPassthroughServiceImplementation<audio::effect::V4_0::IEffectsFactory>() != OK && registerPassthroughServiceImplementation<audio::effect::V2_0::IEffectsFactory>() != OK,
LOG_ALWAYS_FATAL_IF(fail, "Could not register audio effect API 2.0 nor 4.0");
fail = registerPassthroughServiceImplementation<soundtrigger::V2_1::ISoundTriggerHw>() != OK && registerPassthroughServiceImplementation<soundtrigger::V2_0::ISoundTriggerHw>() != OK,
ALOGW_IF(fail, "Could not register soundtrigger API 2.0 nor 2.1");
fail = registerPassthroughServiceImplementation<bluetooth::a2dp::V1_0::IBluetoothAudioOffload>() != OK;
ALOGW_IF(fail, "Could not register Bluetooth audio offload 1.0");
joinRpcThreadpool();
}
- registerPassthroughServiceImplementation函数
system/libhidl/transport/include/hidl/LegacySupport.h
/**
* Registers passthrough service implementation.
*/
template<class Interface>
__attribute__((warn_unused_result))
status_t registerPassthroughServiceImplementation(
std::string name = "default") {
//Interface = audio::V4_0::IDevicesFactory 通过getService函数来获取直通服务
sp<Interface> service = Interface::getService(name, true /* getStub */);
if (service == nullptr) {
ALOGE("Could not get passthrough implementation for %s/%s.",
Interface::descriptor, name.c_str());
return EXIT_FAILURE;
}
LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
Interface::descriptor, name.c_str());
//注册服务到IServiceManager
status_t status = service->registerAsService(name);
if (status == OK) {
ALOGI("Registration complete for %s/%s.",
Interface::descriptor, name.c_str());
} else {
ALOGE("Could not register service %s/%s (%d).",
Interface::descriptor, name.c_str(), status);
}
return status;
}
- IDevicesFactory::getService函数
out/soong/.intermediates/hardware/interfaces/audio/4.0/android.hardware.audio@4.0_genc++/gen/android/hardware/audio/4.0/DevicesFactoryAll.cpp
// static
::android::sp<IDevicesFactory> IDevicesFactory::getService(const std::string &serviceName, const bool getStub) {
//此函数的实现在HidlTransportSupport.h中
return ::android::hardware::details::getServiceInternal<BpHwDevicesFactory>(serviceName, true, getStub);
}
- getServiceInternal函数
system/libhidl/transport/include/hidl/HidlTransportSupport.h
template <typename BpType, typename IType = typename BpType::Pure,
typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>,
typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>>
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
using ::android::hidl::base::V1_0::IBase;
/*
* 模板类型
* BpType = android::hardware::audio::V4_0::BpHwDevicesFactory
* BpType::Pure = android::hardware::audio::V4_0::IDevicesFactory
* IType::descriptor = "android.hardware.audio@4.0::IDevicesFactory"
*/
sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
if (base == nullptr) {
return nullptr;
}
if (base->isRemote()) {
// getRawServiceInternal guarantees we get the proper class
return sp<IType>(new BpType(toBinder<IBase>(base)));
}
return IType::castFrom(base);
}
- getRawServiceInternal函数
system/libhidl/transport/ServiceManagement.cpp
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,const std::string& instance, bool retry, bool getStub) {
using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
using ::android::hidl::base::V1_0::IBase;
using ::android::hidl::manager::V1_0::IServiceManager;
sp<Waiter> waiter;
//获取IServiceManager实例
const sp<IServiceManager1_1> sm = defaultServiceManager1_1();
if (sm == nullptr) {
ALOGE("getService: defaultServiceManager() is null");
return nullptr;
}
//会使用fqname和instance 去vendor/etc/vintf/manifest.xml和system/etc/vintf/manifest.xml下查询transport类型
Return<Transport> transportRet = sm->getTransport(descriptor, instance);
if (!transportRet.isOk()) {
ALOGE("getService: defaultServiceManager()->getTransport returns %s",
transportRet.description().c_str());
return nullptr;
}
Transport transport = transportRet;
const bool vintfHwbinder = (transport == Transport::HWBINDER);
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
忽略好多行
if (waiter != nullptr) {
waiter->done();
}
//LegacySupport.h 中传过来的getStub是true
if (getStub || vintfPassthru || vintfLegacy) {
//getPassthroughServiceManager会得到一个继承了IServiceManager并重写了get函数新增了openLibs函数的PassthroughServiceManager结构体
const sp<IServiceManager> pm = getPassthroughServiceManager();
if (pm != nullptr) {
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}
return nullptr;
}
- PassthroughServiceManager 的get和openLibs函数
system/libhidl/transport/ServiceManagement.cpp
static void openLibs( const std::string& fqName,
const std::function<bool /*continue*/ (void* /*handle*/,
const std::string& /*lib*/, const std::string& /*sym*/)>& eachLib) {
//fqName looks like android.hardware.foo@1.0::IFoo
size_t idx = fqName.find("::");
if (idx == std::string::npos ||
idx + strlen("::") + 1 >= fqName.size()) {
LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
return;
}
std::string packageAndVersion = fqName.substr(0, idx);
std::string ifaceName = fqName.substr(idx + strlen("::"));
const std::string prefix = packageAndVersion + "-impl";
const std::string sym = "HIDL_FETCH_" + ifaceName;
constexpr int dlMode = RTLD_LAZY;
void* handle = nullptr;
dlerror(); // clear
static std::string halLibPathVndkSp = android::base::StringPrintf(
HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, details::getVndkVersionStr().c_str());
std::vector<std::string> paths = {HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, halLibPathVndkSp, HAL_LIBRARY_PATH_SYSTEM};
#ifdef LIBHIDL_TARGET_DEBUGGABLE
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
if (trebleTestingOverride) {
// Load HAL implementations that are statically linked
handle = dlopen(nullptr, dlMode);
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen self: "
<< (error == nullptr ? "unknown error" : error);
} else if (!eachLib(handle, "SELF", sym)) {
return;
}
const char* vtsRootPath = std::getenv("VTS_ROOT_PATH");
if (vtsRootPath && strlen(vtsRootPath) > 0) {
const std::string halLibraryPathVtsOverride =
std::string(vtsRootPath) + HAL_LIBRARY_PATH_SYSTEM;
paths.insert(paths.begin(), halLibraryPathVtsOverride);
}
}
#endif
for (const std::string& path : paths) {
/*
* 这里假设cpu abi是armeabi-v7a path的优先级如下:
* 1、/odm/lib/hw
* 2、/vendor/lib/hw
* 3、/system/lib/vndk-sp%s/hw
* 4、/system/lib/hw
* 在这里其实要到以上目录区找 android.hardware.audio@xx-impl.so
* 具体使用的那个版本的实现要看项目的配置
*/
std::vector<std::string> libs = search(path, prefix, ".so");
for (const std::string &lib : libs) {
const std::string fullPath = path + lib;
//匹配找到的动态库的路径来决定使用那个函数加载动态库
if (path == HAL_LIBRARY_PATH_SYSTEM) {
handle = dlopen(fullPath.c_str(), dlMode);
} else {
handle = android_load_sphal_library(fullPath.c_str(), dlMode);
}
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen " << lib << ": "
<< (error == nullptr ? "unknown error" : error);
continue;
}
//调用传过来的函数
if (!eachLib(handle, lib, sym)) {
return;
}
}
}
}
Return<sp<IBase>> get(const hidl_string& fqName,
const hidl_string& name) override {
sp<IBase> ret = nullptr;
openLibs(fqName, [&](void* handle, const std::string &lib,
const std::string &sym) {
//声明函数指针generator,该函数接受一个const char* 参数
IBase* (*generator)(const char* name);
/
* 通过打开动态可的句柄获得动态库中指定函数的地址
* 在本文中是用的以下文件中的函数:
*
* hardware/interfaces/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.impl.h
* IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* /* name */) {
* return new DevicesFactory();
* }
*/
*(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);
dlclose(handle);
return true;
}
//执行HIDL_FETCH_IDevicesFactory(const char* /*name*/) 返回一个IDevicesFactory类型指针
ret = (*generator)(name.c_str());
if (ret == nullptr) {
dlclose(handle);
return true; // this module doesn't provide this instance name
}
// Actual fqname might be a subclass.
// This assumption is tested in vts_treble_vintf_test
using ::android::hardware::details::getDescriptor;
std::string actualFqName = getDescriptor(ret.get());
CHECK(actualFqName.size() > 0);
registerReference(actualFqName, name);
return false;
});
return ret;
}
- 注册服务到ServiceManager
out/soong/.intermediates/hardware/interfaces/audio/4.0/android.hardware.audio@4.0_genc++/gen/android/hardware/audio/4.0/DevicesFactoryAll.cpp
::android::status_t IDevicesFactory::registerAsService(const std::string &serviceName) {
::android::hardware::details::onRegistration("android.hardware.audio@4.0", "IDevicesFactory", serviceName);
//获取ServiceManager实例
const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm
= ::android::hardware::defaultServiceManager();
if (sm == nullptr) {
return ::android::INVALID_OPERATION;
}
//把服务注册到ServiceManager
::android::hardware::Return<bool> ret = sm->add(serviceName.c_str(), this);
return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;
}
- 初始化&注册完成
使用方式 IDevicesFactory.getService()
audioserver 服务初始化
1. 关联的源码
frameworks/native/libs/binder/include/binder/BinderService.h
frameworks/av/media/audioserver/audioserver.rc
frameworks/av/media/audioserver/main_audioserver.cpp
frameworks/av/services/audioflinger/AudioFlinger.h
frameworks/av/services/audioflinger/AudioFlinger.cpp
frameworks/av/services/audioflinger/AudioPolicyService.h
frameworks/av/services/audioflinger/AudioPolicyService.cpp
frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp
frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp
frameworks/av/media/libaudiohal/DevicesFactoryHalInterface.cpp
frameworks/av/media/libaudiohal/DevicesFactoryHalHybrid.cpp
frameworks/av/media/libaudiohal/4.0/DevicesFactoryHalHybrid.cpp
frameworks/av/media/libaudiohal/4.0/DevicesFactoryHalLocal.cpp
frameworks/av/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
system/media/audio/include/system/audio.h
hardware/libhardware/include/hardware/audio.h
hardware/libhardware/include/hardware/hardware.h
hardware/libhardware/hardware.c
hardware/interfaces/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.impl.h
out/soong/.intermediates/hardware/interfaces/audio/4.0/android.hardware.audio@4.0_genc++/gen/android/hardware/audio/4.0/DevicesFactoryAll.cpp
2. 初始化时序
sequenceDiagram
main_audioserver.cpp -) AudioFlinger.h : instantiate()
AudioFlinger.h -) BinderService.h : instantiate()
BinderService.h -->> BinderService.h : publish()
BinderService.h -) AudioFlinger.cpp : new AudioFlinger()
AudioFlinger.cpp ->> DevicesFactoryHalInterface.cpp : create()
DevicesFactoryHalInterface.cpp ->> IDevicesFactory.cpp : getService()
IDevicesFactory.cpp -->> DevicesFactoryHalInterface.cpp : has Service
DevicesFactoryHalInterface.cpp ->> DevicesFactoryHalHybrid.cpp : new DevicesFactoryHalHybrid()
DevicesFactoryHalHybrid.cpp ->> DevicesFactoryHalHybrid.cpp : new DevicesFactoryHalHidl()
DevicesFactoryHalHybrid.cpp ->> DevicesFactoryHalHybrid.cpp : new DevicesFactoryHalLocal()
DevicesFactoryHalHybrid.cpp -->> AudioFlinger.cpp : return DevicesFactoryHalInterface
main_audioserver.cpp -) AudioPolicyService.cpp : instaniate() publish() 如同AudioFlinger
AudioPolicyService.cpp ->> AudioPolicyClient.cpp : new AudioPolicyClient()
AudioPolicyClient.cpp -->> AudioPolicyService.cpp : reture AudioPolicyClient()
AudioPolicyService.cpp ->> AudioPolicyFactory.cpp : createAudioPolicyManager()
AudioPolicyFactory.cpp ->> AudioPolicyManager.cpp : new AudioPolicyManager
AudioPolicyManager.cpp -) AudioPolicyConfig.cpp : init AudioPolicyConfig
AudioPolicyManager.cpp -->> AudioPolicyManager.cpp : loadConfig()
AudioPolicyManager.cpp -->> AudioPolicyManager.cpp : initialize()
AudioPolicyFactory.cpp -->> AudioPolicyService.cpp : return AudioPolicyManager
3. 初始化详细
- 初始化AIL定义:
frameworks/av/media/audioserver/audioserver.rc
service audioserver /system/bin/audioserver
class core
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
ioprio rt 4
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
onrestart restart vendor.audio-hal-2-0
# Keep the original service name for backward compatibility when upgrading
# O-MR1 devices with framework-only.
onrestart restart audio-hal-2-0
on property:vts.native_server.on=1
stop audioserver
on property:vts.native_server.on=0
start audioserver
这里定义了一个服务
进程名称:audioserver
类型:core
所属用户:audioserver
core类型的服务会在init.rc中定义的boot阶段被统一启动(hal类型启动之后)
class_start core
- main函数
frameworks/av/media/audioserver/main_audioserver.cpp
int main(int argc __unused, char **argv)
{
// TODO: update with refined parameters
limitProcessMemory(
"audio.maxmem", /* "ro.audio.maxmem", property that defines limit */
(size_t)512 * (1 << 20), /* SIZE_MAX, upper limit in bytes */
20 /* upper limit as percentage of physical RAM */);
signal(SIGPIPE, SIG_IGN);
bool doLog = (bool) property_get_bool("ro.test_harness", 0);
//忽略部分代码
// all other services
if (doLog) {
// if parent media.log dies before me, kill me also
prctl(PR_SET_PDEATHSIG, SIGKILL);
// but if I die first, don't kill my parent
setpgid(0, 0);
}
//mmap hwbinder 并设设置最大线程
android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/);
//mmap binder
sp<ProcessState> proc(ProcessState::self());
//获取android::IServiceManager实例
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
//初始化AudioFlinger
AudioFlinger::instantiate();
//初始化AudioPolicyService
AudioPolicyService::instantiate();
// AAudioService should only be used in OC-MR1 and later.
// And only enable the AAudioService if the system MMAP policy explicitly allows it.
// This prevents a client from misusing AAudioService when it is not supported.
aaudio_policy_t mmapPolicy = property_get_int32(AAUDIO_PROP_MMAP_POLICY,
AAUDIO_POLICY_NEVER);
if (mmapPolicy == AAUDIO_POLICY_AUTO || mmapPolicy == AAUDIO_POLICY_ALWAYS) {
AAudioService::instantiate();
}
SoundTriggerHwService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
- AudioFlinger::installtiate
frameworks/native/libs/binder/include/binder/BinderService.h
namespace android {
template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(),
allowIsolated, dumpFlags);
}
static void publishAndJoinThreadPool(
bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
publish(allowIsolated, dumpFlags);
joinThreadPool();
}
//继承BinderService模板类都可以使用这个函数进行发布
static void instantiate() { publish(); }
static status_t shutdown() { return NO_ERROR; }
private:
static void joinThreadPool() {
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
ps->giveThreadPoolName();
IPCThreadState::self()->joinThreadPool();
}
};
}; // namespace android
- AudioFlinger构造函数
frameworks/av/services/audioflinger/AudioFlinger.cpp
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
xxx
{
xxx
//初始化 DevicesFactoryHalInterface 等待初始化 AudioPolicyService时使用
mDevicesFactoryHal = DevicesFactoryHalInterface::create();
mEffectsFactoryHal = EffectsFactoryHalInterface::create();
mMediaLogNotifier->run("MediaLogNotifier");
}
- DevicesFactoryHalInterface::create
frameworks/av/media/libaudiohal/DevicesFactoryHalInterface.cpp
#include <android/hardware/audio/2.0/IDevicesFactory.h>
#include <android/hardware/audio/4.0/IDevicesFactory.h>
#include <DevicesFactoryHalHybrid.h>
#include <libaudiohal/4.0/DevicesFactoryHalHybrid.h>
namespace android {
// static
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
//本文还是使用4.0
if (hardware::audio::V4_0::IDevicesFactory::getService() != nullptr) {
return new V4_0::DevicesFactoryHalHybrid();
}
if (hardware::audio::V2_0::IDevicesFactory::getService() != nullptr) {
return new DevicesFactoryHalHybrid();
}
return nullptr;
}
}
- DevicesFactoryHalHybrid
frameworks/av/media/libaudiohal/DevicesFactoryHalHybrid.cpp
DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
: mLocalFactory(new DevicesFactoryHalLocal()),
mHidlFactory(new DevicesFactoryHalHidl()) {
}
//此函数在解析完audio_policy_xxx.xml后会被调用
status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0 &&
strcmp(AUDIO_HARDWARE_MODULE_ID_HEARING_AID, name) != 0) {
//当设备不是蓝牙设备时
return mHidlFactory->openDevice(name, device);
}
//当设备是蓝牙设备时
return mLocalFactory->openDevice(name, device);
}
- AudioPolicyService::installtiate
如 AudioFlinger 一样使用 BinderService的publish函数发布服务
- AudioPolicyService::onFirstRef()
void AudioPolicyService::onFirstRef()
{
xxx
//初始化AudioPolicyClient包含AudioPolicyService
mAudioPolicyClient = new AudioPolicyClient(this);
//初始化AudioPolicyManager
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
xxxx
}
- 初始化AudioPolicyManager
frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp
#include "managerdefault/AudioPolicyManager.h"
namespace android {
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
return new AudioPolicyManager(clientInterface);
}
extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
delete interface;
}
} // namespace android
frameworks/av/service/audiopolicy/managerdefault/AudioPolicyManager.cpp
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
bool /*forTesting*/)
:mUidCached(getuid()),
mpClientInterface(clientInterface),
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false),
#ifdef USE_XML_AUDIO_POLICY_CONF //基本这个值都是会被定义的
//初始化一个空的音量曲线集合
mVolumeCurves(new VolumeCurvesCollection()),
//初始化一个空的音量曲线集合
mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
mDefaultOutputDevice, static_cast<VolumeCurvesCollection*>(mVolumeCurves.get())),
#else
mVolumeCurves(new StreamDescriptorCollection()),
mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
mDefaultOutputDevice),
#endif
mAudioPortGeneration(1),
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
mBeaconMuted(false),
mTtsOutputAvailable(false),
mMasterMono(false),
mMusicEffectOutput(AUDIO_IO_HANDLE_NONE),
mHasComputedSoundTriggerSupportsConcurrentCapture(false)
{
//nothing
}
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
: AudioPolicyManager(clientInterface, false /*forTesting*/)
{
//解析平台audio_policy_configuration.xml并初始化mConfig
loadConfig();
//根据mConfig中的配置去打开模块,可以打开的模块记录到mHwModules,并更新可用输出、可用输入设备列表及连接状态
initialize();
}
status_t AudioPolicyManager::initialize() {
mVolumeCurves->initializeVolumeCurves(getConfig().isSpeakerDrcEnabled());
// Once policy config has been parsed, retrieve an instance of the engine and initialize it.
audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
if (!engineInstance) {
ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__);
return NO_INIT;
}
// Retrieve the Policy Manager Interface
mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
if (mEngine == NULL) {
ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
return NO_INIT;
}
mEngine->setObserver(this);
status_t status = mEngine->initCheck();
if (status != NO_ERROR) {
LOG_FATAL("Policy engine not initialized(err=%d)", status);
return status;
}
// mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
// open all output streams needed to access attached devices
audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
//下面这个for循环会逐个打开audio plolicy config 文件中配置的设备
for (const auto& hwModule : mHwModulesAll) {
hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
ALOGW("could not open HW module %s", hwModule->getName());
continue;
}
//记录已经定义并可以打开的设备
mHwModules.push_back(hwModule);
// open all output streams needed to access attached devices
// except for direct output streams that are only opened when they are actually
// required by an app.
// This also validates mAvailableOutputDevices list
for (const auto& outProfile : hwModule->getOutputProfiles()) {
if (!outProfile->canOpenNewIo()) {
ALOGE("Invalid Output profile max open count %u for profile %s",
outProfile->maxOpenCount, outProfile->getTagName().c_str());
continue;
}
if (!outProfile->hasSupportedDevices()) {
ALOGW("Output profile contains no device on module %s", hwModule->getName());
continue;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
mTtsOutputAvailable = true;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
continue;
}
audio_devices_t profileType = outProfile->getSupportedDevicesType();
if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
profileType = mDefaultOutputDevice->type();
} else {
// chose first device present in profile's SupportedDevices also part of
// outputDeviceTypes
profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
}
if ((profileType & outputDeviceTypes) == 0) {
continue;
}
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
mpClientInterface);
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
: String8("");
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
status_t status = outputDesc->open(nullptr, profileType, address,
AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
if (status != NO_ERROR) {
ALOGW("Cannot open output stream for device %08x on hw module %s",
outputDesc->mDevice,
hwModule->getName());
} else {
for (const auto& dev : supportedDevices) {
ssize_t index = mAvailableOutputDevices.indexOf(dev);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
mAvailableOutputDevices[index]->attach(hwModule);
}
}
if (mPrimaryOutput == 0 &&
outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
mPrimaryOutput = outputDesc;
}
addOutput(output, outputDesc);
setOutputDevice(outputDesc,
profileType,
true,
0,
NULL,
address);
}
}
// open input streams needed to access attached devices to validate
// mAvailableInputDevices list
for (const auto& inProfile : hwModule->getInputProfiles()) {
if (!inProfile->canOpenNewIo()) {
ALOGE("Invalid Input profile max open count %u for profile %s",
inProfile->maxOpenCount, inProfile->getTagName().c_str());
continue;
}
if (!inProfile->hasSupportedDevices()) {
ALOGW("Input profile contains no device on module %s", hwModule->getName());
continue;
}
// chose first device present in profile's SupportedDevices also part of
// inputDeviceTypes
audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
if ((profileType & inputDeviceTypes) == 0) {
continue;
}
sp<AudioInputDescriptor> inputDesc =
new AudioInputDescriptor(inProfile, mpClientInterface);
DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
// the inputs vector must be of size >= 1, but we don't want to crash here
String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
: String8("");
ALOGV(" for input device 0x%x using address %s", profileType, address.string());
ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = inputDesc->open(nullptr,
profileType,
address,
AUDIO_SOURCE_MIC,
AUDIO_INPUT_FLAG_NONE,
&input);
if (status == NO_ERROR) {
for (const auto& dev : inProfile->getSupportedDevices()) {
ssize_t index = mAvailableInputDevices.indexOf(dev);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0) {
sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
if (!devDesc->isAttached()) {
devDesc->attach(hwModule);
devDesc->importAudioPort(inProfile, true);
}
}
}
inputDesc->close();
} else {
ALOGW("Cannot open input stream for device %08x on hw module %s",
profileType,
hwModule->getName());
}
}
}
// make sure all attached devices have been allocated a unique ID
for (size_t i = 0; i < mAvailableOutputDevices.size();) {
if (!mAvailableOutputDevices[i]->isAttached()) {
ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
for (size_t i = 0; i < mAvailableInputDevices.size();) {
if (!mAvailableInputDevices[i]->isAttached()) {
ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
mAvailableInputDevices.remove(mAvailableInputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
// make sure default device is reachable
if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
status = NO_INIT;
}
// If microphones address is empty, set it according to device type
for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
} else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
}
}
}
if (mPrimaryOutput == 0) {
ALOGE("Failed to open primary output");
status = NO_INIT;
}
updateDevicesAndOutputs();
return status;
}
- loadHwModule的实现
frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp
/* implementation of the client interface from the policy manager */
audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
ALOGW("%s: could not get AudioFlinger", __func__);
return AUDIO_MODULE_HANDLE_NONE;
}
return af->loadHwModule(name);
}
frameworks/av/services/audioflinger/AudioFlinger.cpp
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{
if (name == NULL) {
return AUDIO_MODULE_HANDLE_NONE;
}
if (!settingsAllowed()) {
return AUDIO_MODULE_HANDLE_NONE;
}
Mutex::Autolock _l(mLock);
return loadHwModule_l(name);
}
// loadHwModule_l() must be called with AudioFlinger::mLock held
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
//判断是否已经加载过
if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
ALOGW("loadHwModule() module %s already loaded", name);
return mAudioHwDevs.keyAt(i);
}
}
sp<DeviceHalInterface> dev;
//根据module名称打开设备
int rc = mDevicesFactoryHal->openDevice(name, &dev);
if (rc) {
ALOGE("loadHwModule() error %d loading module %s", rc, name);
return AUDIO_MODULE_HANDLE_NONE;
}
mHardwareStatus = AUDIO_HW_INIT;
rc = dev->initCheck();
mHardwareStatus = AUDIO_HW_IDLE;
if (rc) {
ALOGE("loadHwModule() init check error %d for module %s", rc, name);
return AUDIO_MODULE_HANDLE_NONE;
}
// Check and cache this HAL's level of support for master mute and master
// volume. If this is the first HAL opened, and it supports the get
// methods, use the initial values provided by the HAL as the current
// master mute and volume settings.
AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
{ // scope for auto-lock pattern
AutoMutex lock(mHardwareLock);
if (0 == mAudioHwDevs.size()) {
mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
float mv;
if (OK == dev->getMasterVolume(&mv)) {
mMasterVolume = mv;
}
mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
bool mm;
if (OK == dev->getMasterMute(&mm)) {
mMasterMute = mm;
}
}
mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
if (OK == dev->setMasterVolume(mMasterVolume)) {
flags = static_cast<AudioHwDevice::Flags>(flags |
AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
}
mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
if (OK == dev->setMasterMute(mMasterMute)) {
flags = static_cast<AudioHwDevice::Flags>(flags |
AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
}
mHardwareStatus = AUDIO_HW_IDLE;
}
audio_module_handle_t handle = (audio_module_handle_t)
nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
//保存成功打开的设备
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
ALOGI("loadHwModule() Loaded %s audio interface, handle %d", name, handle);
return handle;
}
- openDevice的实现
openDevice有两个实现,根据不同的module来调用不同的实现 system/media/audio/include/system/audio.h
/**
* List of known audio HAL modules. This is the base name of the audio HAL
* library composed of the "audio." prefix, one of the base names below and
* a suffix specific to the device.
* e.g: audio.primary.goldfish.so or audio.a2dp.default.so
*
* The same module names are used in audio policy configuration files.
*/
#define AUDIO_HARDWARE_MODULE_ID_PRIMARY "primary"
#define AUDIO_HARDWARE_MODULE_ID_A2DP "a2dp"
#define AUDIO_HARDWARE_MODULE_ID_USB "usb"
#define AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX "r_submix"
#define AUDIO_HARDWARE_MODULE_ID_CODEC_OFFLOAD "codec_offload"
#define AUDIO_HARDWARE_MODULE_ID_STUB "stub"
#define AUDIO_HARDWARE_MODULE_ID_HEARING_AID "hearing_aid"
//AUDIO_HARDWARE_MODULE_ID_A2DP 和 AUDIO_HARDWARE_MODULE_ID_HEARING_AID 会使用DevicesFactoryHalLocal的实现,其它MODULE使用DevicesFactoryHalHidl的实现
- DevicesFactoryHalHidl中的openDevice实现流程
sequenceDiagram
DevicesFactoryHalHidl.cpp ->> DevicesFactoryAll.cpp : openDevice()
DevicesFactoryAll.cpp -->> DevicesFactoryAll.cpp : BpHwDevicesFactory::_hidl_openDevice()
DevicesFactoryAll.cpp -) BpHwBinder.cpp : transact()
BpHwBinder.cpp -) IPCThreadState.cpp : transact()
IPCThreadState.cpp -->> IPCThreadState.cpp : waitForResponse()
IPCThreadState.cpp -->> DevicesFactoryAll.cpp : onTransact()
DevicesFactoryAll.cpp -->> DevicesFactoryAll.cpp : BnHwDevicesFactory::_hidl_openDevice()
DevicesFactoryAll.cpp ->> DevicesFactory.impl.h : openDevice()
DevicesFactory.impl.h -->> DevicesFactory.impl.h : loadAudioInterface()
DevicesFactory.impl.h -->> hardware.c : hw_get_module_by_class()
DevicesFactory.impl.h -->> audio.h : audio_hw_device_open()
DevicesFactory.impl.h -->> DevicesFactoryAll.cpp : callback
DevicesFactoryAll.cpp -->> DevicesFactoryHalHidl.cpp : callback
- DevicesFactoryHalLocal中的openDevice实现流程
sequenceDiagram
DevicesFactoryHalLocal.cpp -->> DevicesFactoryHalLocal.cpp : load_audio_interface()
DevicesFactoryHalLocal.cpp -->> hardware.c : hw_get_module_by_class()
DevicesFactoryHalLocal.cpp -->> audio.h : audio_hw_device_open()
- 两种openDevice的实现最后还是去加载模块&打开设备
hardware/libhardware/hardware.c
#include <hardware/hardware.h>
#include <cutils/properties.h>
#include <dlfcn.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#define LOG_TAG "HAL"
#include <log/log.h>
#include <vndksupport/linker.h>
/** Base path of the hal modules */
#if defined(__LP64__)
#define HAL_LIBRARY_PATH1 "/system/lib64/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib64/hw"
#define HAL_LIBRARY_PATH3 "/odm/lib64/hw"
#else
#define HAL_LIBRARY_PATH1 "/system/lib/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"
#define HAL_LIBRARY_PATH3 "/odm/lib/hw"
#endif
/**
* There are a set of variant filename for modules. The form of the filename
* is "<MODULE_ID>.variant.so" so for the led module the Dream variants
* of base "ro.product.board", "ro.board.platform" and "ro.arch" would be:
*
* led.trout.so
* led.msm7k.so
* led.ARMV6.so
* led.default.so
*/
static const char *variant_keys[] = {
"ro.hardware", /* This goes first so that it can pick up a different file on the emulator. */
"ro.product.board",
"ro.board.platform",
"ro.arch"
};
static const int HAL_VARIANT_KEYS_COUNT =
(sizeof(variant_keys)/sizeof(variant_keys[0]));
/**
* Load the file defined by the variant and if successful
* return the dlopen handle and the hmi.
* @return 0 = success, !0 = failure.
*/
static int load(const char *id,
const char *path,
const struct hw_module_t **pHmi)
{
int status = -EINVAL;
void *handle = NULL;
struct hw_module_t *hmi = NULL;
#ifdef __ANDROID_VNDK__
const bool try_system = false;
#else
const bool try_system = true;
#endif
/*
* load the symbols resolving undefined symbols before
* dlopen returns. Since RTLD_GLOBAL is not or'd in with
* RTLD_NOW the external symbols will not be global
*/
//打开模块获得句柄
if (try_system &&
strncmp(path, HAL_LIBRARY_PATH1, strlen(HAL_LIBRARY_PATH1)) == 0) {
/* If the library is in system partition, no need to check
* sphal namespace. Open it with dlopen.
*/
handle = dlopen(path, RTLD_NOW);
} else {
handle = android_load_sphal_library(path, RTLD_NOW);
}
if (handle == NULL) {
char const *err_str = dlerror();
ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
status = -EINVAL;
goto done;
}
/* Get the address of the struct hal_module_info. */
/* 硬件抽象层的规范,每个模块都必须有这个符号:HAL_MODULE_INFO_SYM_AS_STR 并用来描述一个类型为hw_module_t的结构体 */
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
hmi = (struct hw_module_t *)dlsym(handle, sym);
if (hmi == NULL) {
ALOGE("load: couldn't find symbol %s", sym);
status = -EINVAL;
goto done;
}
/* Check that the id matches */
if (strcmp(id, hmi->id) != 0) {
ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);
status = -EINVAL;
goto done;
}
hmi->dso = handle;
/* success */
status = 0;
done:
if (status != 0) {
hmi = NULL;
if (handle != NULL) {
dlclose(handle);
handle = NULL;
}
} else {
ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
id, path, *pHmi, handle);
}
*pHmi = hmi;
return status;
}
/*
* Check if a HAL with given name and subname exists, if so return 0, otherwise
* otherwise return negative. On success path will contain the path to the HAL.
*/
static int hw_module_exists(char *path, size_t path_len, const char *name,
const char *subname)
{
snprintf(path, path_len, "%s/%s.%s.so",
HAL_LIBRARY_PATH3, name, subname);
if (access(path, R_OK) == 0)
return 0;
snprintf(path, path_len, "%s/%s.%s.so",
HAL_LIBRARY_PATH2, name, subname);
if (access(path, R_OK) == 0)
return 0;
#ifndef __ANDROID_VNDK__
snprintf(path, path_len, "%s/%s.%s.so",
HAL_LIBRARY_PATH1, name, subname);
if (access(path, R_OK) == 0)
return 0;
#endif
return -ENOENT;
}
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module)
{
int i = 0;
char prop[PATH_MAX] = {0};
char path[PATH_MAX] = {0};
char name[PATH_MAX] = {0};
char prop_name[PATH_MAX] = {0};
if (inst)
//module名称存在,拼接模块名称
snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
else
strlcpy(name, class_id, PATH_MAX);
/*
* Here we rely on the fact that calling dlopen multiple times on
* the same .so will simply increment a refcount (and not load
* a new copy of the library).
* We also assume that dlopen() is thread-safe.
*/
/* 检查是否使用客制化模块 */
snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);
if (property_get(prop_name, prop, NULL) > 0) {
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}
/* 遍历配置变体以查找模块,检查是否有客制化模块 */
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}
/* 没有找到任何模块,检查是否有默认的模块 */
if (hw_module_exists(path, sizeof(path), name, "default") == 0) {
goto found;
}
/* 没有找到模块 */
return -ENOENT;
found:
/* 开始加载模块,如果失败就认命吧,我们不应该尝试加载不同的变体 */
return load(class_id, path, module);
}
int hw_get_module(const char *id, const struct hw_module_t **module)
{
return hw_get_module_by_class(id, NULL, module);
}
hardware/libhardware/include/hardware/audio.h
typedef struct audio_hw_device audio_hw_device_t;
/** convenience API for opening and closing a supported device */
/* 打开设备 */
static inline int audio_hw_device_open(const struct hw_module_t* module,
struct audio_hw_device** device)
{
return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,
TO_HW_DEVICE_T_OPEN(device));
}
static inline int audio_hw_device_close(struct audio_hw_device* device)
{
return device->common.close(&device->common);
}