Android audioserver 学习笔记1

672 阅读17分钟

概述

基于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);
}