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 : android.hardware.audio@6.0::IDevicesFactory
 //   expectInterfaceName : android.hardware.audio@6.0::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 : android.hardware.audio@6.0::IDevicesFactory
 //   expectInterfaceName : android.hardware.audio@6.0::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 : android.hardware.audio@6.0::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 : android.hardware.audio@6.0::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 : android.hardware.audio@6.0-impl.so
    // 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 : android.hardware.audio@6.0::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 : android.hardware.audio@6.0::IDevicesFactory
        size_t idx = fqName.find("::");
        // android.hardware.audio@6.0
        std::string packageAndVersion = fqName.substr(0, idx);
        // IDevicesFactory
        std::string ifaceName = fqName.substr(idx + strlen("::"));
        // android.hardware.audio@6.0-impl
        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/android.hardware.audio@6.0-impl.so
                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/android.hardware.audio@6.0-impl.so
                    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 : android.hardware.audio@6.0::IDevicesFactory  
// instanceName : default
fqName android.hardware.audio@6.0::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;
}

关于 android.hardware.audio@6.0-impl.so

android.bp 编译

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

cc_library_shared {
    name: "android.hardware.audio@6.0-impl",
    defaults: ["android.hardware.audio@6.0-impl_default"],
}

android.hardware.audio@6.0-impl 源代码

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

相关推荐
maki0778 小时前
虚幻版Pico大空间VR入门教程 05 —— 原点坐标和项目优化技巧整理
android·游戏引擎·vr·虚幻·pico·htc vive·大空间
千里马学框架9 小时前
音频焦点学习之AudioFocusRequest.Builder类剖析
android·面试·智能手机·车载系统·音视频·安卓framework开发·audio
fundroid12 小时前
掌握 Compose 性能优化三步法
android·android jetpack
TeleostNaCl13 小时前
如何在 IDEA 中使用 Proguard 自动混淆 Gradle 编译的Java 项目
android·java·经验分享·kotlin·gradle·intellij-idea
旷野说14 小时前
Android Studio Narwhal 3 特性
android·ide·android studio
maki07720 小时前
VR大空间资料 01 —— 常用VR框架对比
android·ue5·游戏引擎·vr·虚幻·pico
xhBruce1 天前
InputReader与InputDispatcher关系 - android-15.0.0_r23
android·ims
领创工作室1 天前
安卓设备分区作用详解-测试机红米K40
android·java·linux
hello_ludy1 天前
Android 中的 mk 和 bp 文件编译说明
android·编译
maki0771 天前
VR大空间资料 03 —— VRGK使用体验和源码分析
android·vr·虚幻·源码分析·oculus·htc vive·vrgk