Audio Hal 介绍

Audio HAL(Hardware Abstraction Layer)是 Android 音频系统和底层音频驱动之间的桥梁,负责提供统一的接口,让 AudioFlinger(音频框架)可以与不同的音频硬件通信。它位于 Android 音频架构的 Framework 层驱动层 之间。

vendor.audio-hal 服务启动

以车载模拟器代码为例

系统启动时 init 进程会启动 vendor.audio-hal 服务

kotlin 复制代码
service vendor.audio-hal /vendor/bin/hw/android.hardware.audio.service-caremu
    override
    class hal
    user audioserver
    # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
    capabilities BLOCK_SUSPEND
    ioprio rt 4
    task_profiles ProcessCapacityHigh HighPerformance

/vendor/bin/hw/android.hardware.audio.service-caremu 源代码

这个程序的功能主要是

  • 注册 2 个 HIDL 服务到 hwservicemanger
    • IDevicesFactory 创建音频输入输出设备接口
    • IEffectsFactory 音频效果处理接口
  • 注册 1 个 aidl 接口到 servicemangaer
    • AudioControl 车载音频控制
cpp 复制代码
int main(int /* argc */, char* /* argv */ []) {
    // Setup HIDL Audio HAL
    LOG(INFO) << "AudioControl start audio HAL.";
    // 配置 HIDL 线程池最大线程数 
    configureRpcThreadpool(16, false /*callerWillJoin*/);
    android::status_t status;
    // 注册 IDevicesFactory HIDL 接口
    status = registerPassthroughServiceImplementation<IDevicesFactory>();
    LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio service: %d", status);
    // 注册 IEffectsFactory HIDL 接口
    status = registerPassthroughServiceImplementation<IEffectsFactory>();
    LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio effects service: %d", status);

    // 设置 aidl 线程池最大线程数
    ABinderProcess_setThreadPoolMaxThreadCount(16);
    std::shared_ptr<AudioControl> audioControl = ::ndk::SharedRefBase::make<AudioControl>();

    const std::string instance = std::string() + AudioControl::descriptor + "/default";
    // 把 AudioControl 添加到 binder 系统服务中 
    binder_status_t aidlStatus = AServiceManager_addService(audioControl->asBinder().get(),
            instance.c_str());
    CHECK(aidlStatus == STATUS_OK);

    LOG(INFO) << "AudioControl status: status " << aidlStatus;
   // 进入binder线程池循环,等待 binder 内核发出来的消息
    ABinderProcess_joinThreadPool();
    LOG(ERROR) << "ABinderProcess_joinThreadPool should never get here ";
    return EXIT_FAILURE;  // should not reach
}

IDevicesFactory 注册到 hwservicemanager

cpp 复制代码
// Interface 和 ExpectInterface 都是 IDevicesFactory
template <class Interface, class ExpectInterface = Interface>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
        const std::string& name = "default") {
    return registerPassthroughServiceImplementation(Interface::descriptor,
                                                    ExpectInterface::descriptor, name);
}

 //  interfaceName : [email protected]::IDevicesFactory
 //   expectInterfaceName : [email protected]::IDevicesFactory
 //   serviceName : default
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
        const std::string& interfaceName, const std::string& expectInterfaceName,
        const std::string& serviceName) {

    return details::registerPassthroughServiceImplementation(
            interfaceName, expectInterfaceName,
            // RegisterServiceCb ,lambda 表示式 
            [](const sp<IBase>& service, const std::string& name) {
                // service 为 DevicesFactory ,name 为 default
                return details::registerAsServiceInternal(service, name);
            },
            serviceName);
}

using RegisterServiceCb =
        std::function<status_t(const sp<::android::hidl::base::V1_0::IBase>&, const std::string&)>;
        
  //  interfaceName : [email protected]::IDevicesFactory
 //   expectInterfaceName : [email protected]::IDevicesFactory
 //   registerServiceCb : lambda 表示式 callback 
 //   serviceName : default       
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
        const std::string& interfaceName, const std::string& expectInterfaceName,
        RegisterServiceCb registerServiceCb, const std::string& serviceName) {
    // 调用 getRawServiceInternal 获取  sp<IBase>
    sp<IBase> service =
            getRawServiceInternal(interfaceName, serviceName, true /*retry*/, true /*getStub*/);

    // 回调 registerServiceCb 
    status_t status = registerServiceCb(service, serviceName);
    if (status == OK) {
        ALOGI("Registration complete for %s/%s.", interfaceName.c_str(), serviceName.c_str());
    } else {
        ALOGE("Could not register service %s/%s (%d).", interfaceName.c_str(), serviceName.c_str(),
              status);
    }

    return status;
}

// service 为 DevicesFactory ,name 为 default
status_t registerAsServiceInternal(const sp<IBase>& service, const std::string& name) {
    if (service == nullptr) {
        return UNEXPECTED_NULL;
    }
    // 获取 hwservicemanager 
    sp<IServiceManager1_2> sm = defaultServiceManager1_2();
    if (sm == nullptr) {
        return INVALID_OPERATION;
    }
    const std::string descriptor = getDescriptor(service.get());
    if (kEnforceVintfManifest && !isTrebleTestingOverride()) {
        using Transport = IServiceManager1_0::Transport;
        Return<Transport> transport = sm->getTransport(descriptor, name);
        if (!transport.isOk()) {
            LOG(ERROR) << "Could not get transport for " << descriptor << "/" << name << ": "
                       << transport.description();
            return UNKNOWN_ERROR;
        }

        if (transport != Transport::HWBINDER) {
            LOG(ERROR) << "Service " << descriptor << "/" << name
                       << " must be in VINTF manifest in order to register/get.";
            return UNKNOWN_ERROR;
        }
    }

    bool registered = false;
    Return<void> ret = service->interfaceChain([&](const auto& chain) {
        // 把 DevicesFactory 添加到 hwservicemanager 
        registered = sm->addWithChain(name.c_str(), service, chain).withDefault(false);
    });

    if (!ret.isOk()) {
        LOG(ERROR) << "Could not retrieve interface chain: " << ret.description();
    }

    if (registered) {
        onRegistrationImpl(descriptor, name);
    }

    return registered ? OK : UNKNOWN_ERROR;
}
cpp 复制代码
  // descriptor : [email protected]::IDevicesFactory
 //  instance : default   
 //  retry : true
 //  getStub : true
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance, bool retry, bool getStub) {
    using Transport = IServiceManager1_0::Transport;
    sp<IServiceManager1_1> sm;
    Transport transport = Transport::EMPTY;
    if (kIsRecovery) {
        transport = Transport::PASSTHROUGH;
    } else {
        // 获取 hwservicemanager
        sm = defaultServiceManager1_1();
        if (sm == nullptr) {
            ALOGE("getService: defaultServiceManager() is null");
            return nullptr;
        }
        Return<Transport> transportRet = sm->getTransport(descriptor, instance);
        if (!transportRet.isOk()) {
            ALOGE("getService: defaultServiceManager()->getTransport returns %s",
                  transportRet.description().c_str());
            return nullptr;
        }
        transport = transportRet;
    }

    const bool vintfHwbinder = (transport == Transport::HWBINDER);
    const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
    const bool trebleTestingOverride = isTrebleTestingOverride();
    const bool allowLegacy = !kEnforceVintfManifest || (trebleTestingOverride && isDebuggable());
    const bool vintfLegacy = (transport == Transport::EMPTY) && allowLegacy;

    // getStub 为 true 
    if (getStub || vintfPassthru || vintfLegacy) {
        // 获取 HIDL 直通(Passthrough)服务管理者 
        const sp<IServiceManager1_0> pm = getPassthroughServiceManager();
        if (pm != nullptr) {
            // 调用 get 方法
            sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
            if (!getStub || trebleTestingOverride) {
                base = wrapPassthrough(base);
            }
            return base;
        }
    }

    return nullptr;
}

sp<IServiceManager1_0> getPassthroughServiceManager() {
    return getPassthroughServiceManager1_1();
}
sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
    static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
    return manager;
}

struct PassthroughServiceManager : IServiceManager1_1 {

 // fqName : [email protected]::IDevicesFactory
 // name : default   
Return<sp<IBase>> get(const hidl_string& fqName,
                      const hidl_string& name) override {

    sp<IBase> ret = nullptr;
    // 调用 openLibs 加载 so 
    // handle : 动态库的句柄(`void*` 指针)
    // lib : [email protected]
    // sym : HIDL_FETCH_IDevicesFactory
    openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
        // 定义函数指针
        IBase* (*generator)(const char* name);
        // 从 so 里面加载 HIDL_FETCH_IDevicesFactory 方法 
        *(void **)(&generator) = dlsym(handle, sym.c_str());
        if(!generator) {
            const char* error = dlerror();
            LOG(ERROR) << "Passthrough lookup opened " << lib << " but could not find symbol "
                       << sym << ": " << (error == nullptr ? "unknown error" : error)
                       << ". Keeping library open.";
            return true;  // continue
        }
        // 调用 generator( HIDL_FETCH_IDevicesFactory )函数 
        ret = (*generator)(name.c_str());

        if (ret == nullptr) {
            LOG(ERROR) << "Could not find instance '" << name.c_str() << "' in library " << lib
                       << ". Keeping library open.";
            return true;  // continue
        }
        using ::android::hardware::details::getDescriptor;
        std::string actualFqName = getDescriptor(ret.get());
        CHECK(actualFqName.size() > 0);
        registerReference(actualFqName, name);
        return false;
    });
    LOG(DEBUG) << "get name : " << (ret== nullptr);
    return ret;
}
    // fqName : [email protected]::IDevicesFactory
    static void openLibs(
        const std::string& fqName,
        const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
                                                 const std::string& /* sym */)>& eachLib) {
         // fqName : [email protected]::IDevicesFactory
        size_t idx = fqName.find("::");
        // [email protected]
        std::string packageAndVersion = fqName.substr(0, idx);
        // IDevicesFactory
        std::string ifaceName = fqName.substr(idx + strlen("::"));
        // [email protected]
        const std::string prefix = packageAndVersion + "-impl";
        // HIDL_FETCH_IDevicesFactory
        const std::string sym = "HIDL_FETCH_" + ifaceName;

        constexpr int dlMode = RTLD_LAZY;
        void* handle = nullptr;

        dlerror(); // clear

        static std::string halLibPathVndkSp = details::getVndkSpHwPath();
        // 指定搜索路径
        std::vector<std::string> paths = {
            HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, halLibPathVndkSp,
#ifndef __ANDROID_VNDK__
            HAL_LIBRARY_PATH_SYSTEM,
#endif
        };

        for (const std::string& path : paths) {
            std::vector<std::string> libs = findFiles(path, prefix, ".so");
            for (const std::string &lib : libs) {
                // fullPath : /vendor/lib64/hw/[email protected]
                const std::string fullPath = path + lib;

                if (kIsRecovery || path == HAL_LIBRARY_PATH_SYSTEM) {
                    handle = dlopen(fullPath.c_str(), dlMode);
                } else {
#if !defined(__ANDROID_RECOVERY__) && defined(__ANDROID__)
                    // 加载 /vendor/lib64/hw/[email protected]
                    handle = android_load_sphal_library(fullPath.c_str(), dlMode);
#endif
                }

                if (handle == nullptr) {
                    const char* error = dlerror();
                    LOG(ERROR) << "Failed to dlopen " << lib << ": "
                               << (error == nullptr ? "unknown error" : error);
                    continue;
                }
                // 调用 eachLib 函数 
                if (!eachLib(handle, lib, sym)) {
                    return;
                }
            }
        }
    }

// 注册到 hwservicemanager ,做个统计调试用
// interfaceName : [email protected]::IDevicesFactory  
// instanceName : default
fqName [email protected]::IDevicesFactory name default
static void registerReference(const hidl_string &interfaceName, const hidl_string &instanceName) {
    sp<IServiceManager1_0> binderizedManager = defaultServiceManager();
    auto ret = binderizedManager->registerPassthroughClient(interfaceName, instanceName);
    LOG(VERBOSE) << "Successfully registerReference for "
                 << interfaceName << "/" << instanceName;
}

关于 [email protected]

android.bp 编译

cpp 复制代码
cc_defaults {
    name: "[email protected]_default",
    defaults: ["android.hardware.audio-impl_default"],
    shared_libs: [
        "[email protected]",
        "[email protected]",
        "[email protected]",
        "[email protected]",
    ],
    cflags: [
        "-DMAJOR_VERSION=6",
        "-DMINOR_VERSION=0",
        "-include common/all-versions/VersionMacro.h",
    ],
}

cc_library_shared {
    name: "[email protected]",
    defaults: ["[email protected]_default"],
}

[email protected] 源代码

cpp 复制代码
namespace android {
namespace hardware {
namespace audio {
namespace CPP_VERSION {
namespace implementation {

using ::android::sp;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using namespace ::android::hardware::audio::CPP_VERSION;

struct DevicesFactory : public IDevicesFactory {
#if MAJOR_VERSION == 2
    Return<void> openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) override;
#elif MAJOR_VERSION >= 4
    Return<void> openDevice(const hidl_string& device, openDevice_cb _hidl_cb) override;
    Return<void> openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override;
#endif
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
    Return<void> openDevice_7_1(const hidl_string& device, openDevice_7_1_cb _hidl_cb) override;
    Return<void> openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) override;
#endif

  private:
    template <class DeviceShim, class Callback>
    Return<void> openDevice(const char* moduleName, Callback _hidl_cb);
#if MAJOR_VERSION == 2
    Return<void> openDevice(const char* moduleName, openDevice_cb _hidl_cb);
#endif

    static int loadAudioInterface(const char* if_name, audio_hw_device_t** dev);
};

extern "C" IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name);

} 
// 创建 DevicesFactory 对象 
IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name) {
    return strcmp(name, "default") == 0 ? new DevicesFactory() : nullptr;
}

IEffectsFactory 的注册和 IDevicesFactory 类似,不赘述

这里只介绍 IDevicesFactory 和 IEffectsFactory 注册到 hwservicemanager 过程。这两个接口的使用在后面 audioserver 介绍

相关推荐
斗锋在干嘛1 小时前
Android里面内存优化
android
jiet_h2 小时前
深入解析Kapt —— Kotlin Annotation Processing Tool 技术博客
android·开发语言·kotlin
alexhilton3 小时前
实战:探索Jetpack Compose中的SearchBar
android·kotlin·android jetpack
uhakadotcom3 小时前
EventBus:简化组件间通信的利器
android·java·github
笑鸿的学习笔记4 小时前
ROS2笔记之服务通信和基于参数的服务通信区别
android·笔记·microsoft
8931519605 小时前
Android开发融云获取多个会话的总未读数
android·android开发·android教程·融云获取多个会话的总未读数·融云未读数
zjw_swun6 小时前
实现了一个uiautomator玩玩
android
pengyu6 小时前
系统化掌握Dart网络编程之Dio(二):责任链模式篇
android·flutter·dart
水w6 小时前
【Android Studio】如何卸载干净(详细步骤)
android·开发语言·android studio·activity
亦是远方6 小时前
2025华为软件精英挑战赛2600w思路分享
android·java·华为