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 介绍

相关推荐
非凡ghost1 分钟前
LSPatch官方版:无Root Xposed框架,自由定制手机体验
android·智能手机·软件需求
_extraordinary_1 分钟前
MySQL 库的操作 -- 增删改查,备份和恢复,系统编码
android·mysql·oracle
西瓜本瓜@3 小时前
在Android中如何使用Protobuf上传协议
android·java·开发语言·git·学习·android-studio
似霰6 小时前
安卓adb shell串口基础指令
android·adb
fatiaozhang95278 小时前
中兴云电脑W102D_晶晨S905X2_2+16G_mt7661无线_安卓9.0_线刷固件包
android·adb·电视盒子·魔百盒刷机·魔百盒固件
CYRUS_STUDIO9 小时前
Android APP 热修复原理
android·app·hotfix
鸿蒙布道师9 小时前
鸿蒙NEXT开发通知工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
鸿蒙布道师9 小时前
鸿蒙NEXT开发网络相关工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
大耳猫10 小时前
【解决】Android Gradle Sync 报错 Could not read workspace metadata
android·gradle·android studio
ta叫我小白10 小时前
实现 Android 图片信息获取和 EXIF 坐标解析
android·exif·经纬度