Android Audio 服务层与HAL层之间的接口分析 Service<->interface<->HAL

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

一.AudioFlinger

在AudioFlinger.cpp中mDevicesFactoryHal 这个变量出现的频率不高,但是很重要
在AudioPolicyService初始化时,就需要透过接口去获取HAL层的一些代理,从而操作一些方法。

AudioFlinger::AudioFlinger()...{
	...
	//主要分析下面这一行代码
	mDevicesFactoryHal = DevicesFactoryHalInterface::create();
	...
}

二、服务层接口分析

下面会围绕这张图进行分析
在这里插入图片描述

2.1由DevicesFactoryHalInterface可以找到DevicesFactoryHalInterface.cpp这个类

#include <media/audiohal/DevicesFactoryHalInterface.h>
#include <media/audiohal/FactoryHalHidl.h>
namespace android {

sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
    return createPreferredImpl<DevicesFactoryHalInterface>(
            "android.hardware.audio", "IDevicesFactory");
}
} // namespace android

createPreferredImpl是一个模板方法,模板是自己本身,且返回的是自己本身的类型

2.2由FactoryHalHidl.cpp这个类可以找到createPreferredImpl这个方法

const char* sAudioHALVersions[] = {
    "6.0",
    "5.0",
    "4.0",
    "2.0",
    nullptr
};

//这里返回一个指针rawInterface,这个返回值也是上一个方法的返回值,所以,我们主要关注createHalService这个方法
void* createPreferredImpl(const std::string& package, const std::string& interface) {
    for (auto version = detail::sAudioHALVersions; version != nullptr; ++version) {
        void* rawInterface = nullptr;
        if (hasHalService(package, *version, interface)
                && createHalService(*version, interface, &rawInterface)) {
            return rawInterface;
        }
    }
    return nullptr;
}

//rawInterface是一个传入传出参数
bool createHalService(const std::string& version, const std::string& interface,
        void** rawInterface) {
    const std::string libName = "libaudiohal@" + version + ".so";
    const std::string factoryFunctionName = "create" + interface;
    constexpr int dlMode = RTLD_LAZY;
    void* handle = nullptr;
    dlerror(); // clear
    handle = dlopen(libName.c_str(), dlMode);
    if (handle == nullptr) {
        const char* error = dlerror();
        ALOGE("Failed to dlopen %s: %s", libName.c_str(),
                error != nullptr ? error : "unknown error");
        return false;
    }
    void* (*factoryFunction)();
    *(void **)(&factoryFunction) = dlsym(handle, factoryFunctionName.c_str());
    if (!factoryFunction) {
        const char* error = dlerror();
        ALOGE("Factory function %s not found in library %s: %s",
                factoryFunctionName.c_str(), libName.c_str(),
                error != nullptr ? error : "unknown error");
        dlclose(handle);
        return false;
    }else{
        ALOGE("Factory function %s found in library %s ",
                factoryFunctionName.c_str(), libName.c_str());
    }
    //返回rawInterface 
    *rawInterface = (*factoryFunction)();
    ALOGW_IF(!*rawInterface, "Factory function %s from %s returned nullptr",
            factoryFunctionName.c_str(), libName.c_str());
    return true;
}

//直接看LOG,就可以知道它打开的是哪个库了
E FactoryHalHidl: Obtain transport type for android.hardware.audio@6.0::IDevicesFactory/default: No error
E FactoryHalHidl: Factory function createIDevicesFactory found in library libaudiohal@6.0.so 

可知是rawInterface获取的是libaudiohal@6.0.so中的方法createIDevicesFactory,即rawInterface本质上是一个方法的地址,该方法名为createIDevicesFactory,这个方法具体的返回值,我们稍后找到该方法后,再讨论。
已经库的名字是libaudiohal,而这个库刚好是我们正在分析的文件夹内,可以找到DevicesFactoryHalHybrid.cpp具有一个createIDevicesFactory方法,下面,分析createIDevicesFactory.cpp

2.3DevicesFactoryHalHybrid的分析

,主要是分两种情况,一种DevicesFactoryHalLocal,另一种DevicesFactoryHalHidl,主要分析DevicesFactoryHalHidl
这里有个疑惑,就是参考其他博客时,会调用到这个方法,但是,在我的代码里面并没有调用它,而是直接打开了IDevicesFactory found in library libaudiohal@6.0.so ,见

#define LOG_TAG "DevicesFactoryHalHybrid"
//#define LOG_NDEBUG 0

#include "DevicesFactoryHalHidl.h"
#include "DevicesFactoryHalHybrid.h"
#include "DevicesFactoryHalLocal.h"

namespace android {

//这个方法就是上述从库中获取的方法,主要也是调用了其构造函数
//hardware::audio::CPP_VERSION::IDevicesFactory::getService();
//可以知道具体是拿到一个具有不同版本的IDevicesFactory的服务接口,这个服务接口作为构造函数的参数传入
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
    auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
    return service ? new CPP_VERSION::DevicesFactoryHalHybrid(service) : nullptr;
}

namespace CPP_VERSION {

//其构造函数总共会初始化两个参数,mLocalFactory和mHidlFactory,其中mHidlFactory是我们关注的重点
//还有,它传入了一个参数,这个参数是sp<IDevicesFactory> hidlFactory
DevicesFactoryHalHybrid::DevicesFactoryHalHybrid(sp<IDevicesFactory> hidlFactory)
        : mLocalFactory(new DevicesFactoryHalLocal()),
          mHidlFactory(new DevicesFactoryHalHidl(hidlFactory)) {
}
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);
}
......
} // namespace CPP_VERSION
} // namespace android

下面,我们将分析DevicesFactoryHalHidl.cpp这个方法,需要关注的是其构造函数及其在构造中传入的参数,以及openDevice这个方法

2.4 DevicesFactoryHalHidl.cpp分析

#include <string.h>
#include <set>

#define LOG_TAG0 "DevicesFactoryHalHidl"
#define LOG_TAG "KK"

//#define LOG_NDEBUG 0

#include <android/hidl/manager/1.0/IServiceManager.h>
#include <android/hidl/manager/1.0/IServiceNotification.h>
#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
#include <media/audiohal/hidl/HalDeathHandler.h>
#include <utils/Log.h>

#include "ConversionHelperHidl.h"
#include "DeviceHalHidl.h"
#include "DevicesFactoryHalHidl.h"

using ::android::hardware::audio::CPP_VERSION::IDevice;
using ::android::hardware::audio::CPP_VERSION::Result;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hidl::manager::V1_0::IServiceManager;
using ::android::hidl::manager::V1_0::IServiceNotification;

namespace android {
namespace CPP_VERSION {

class ServiceNotificationListener : public IServiceNotification {
  public:
    explicit ServiceNotificationListener(sp<DevicesFactoryHalHidl> factory)
            : mFactory(factory) {}

    Return<void> onRegistration(const hidl_string& /*fully_qualified_name*/,
            const hidl_string& instance_name,
            bool /*pre_existing*/) override {
        if (static_cast<std::string>(instance_name) == "default") return Void();
        sp<DevicesFactoryHalHidl> factory = mFactory.promote();
        if (!factory) return Void();
        sp<IDevicesFactory> halFactory = IDevicesFactory::getService(instance_name);
        if (halFactory) {
            ALOGE("HIDL---------------onRegistration::halFactory ! null ");
            factory->addDeviceFactory(halFactory, true /*needToNotify*/);
        }
        return Void();
    }

  private:
    wp<DevicesFactoryHalHidl> mFactory;
};
//这个类被创建是,就执行addDeviceFactory方法
//注意,sp<IDevicesFactory> devicesFactory这个在2.3中,传入的是hardware::audio::6.0::IDevicesFactory接口
//android.hardware.audio@6.0::IDevicesFactory,
//这个方法,我们稍后会进行分析,只需要这个devicesFactory参数可以远程调用DevicesFactory.cpp这个类的方法
DevicesFactoryHalHidl::DevicesFactoryHalHidl(sp<IDevicesFactory> devicesFactory) {
    ALOG_ASSERT(devicesFactory != nullptr, "Provided default IDevicesFactory service is NULL");
    //devicesFactory这个参数传到了addDeviceFactory,我们将会addDeviceFactory进行分析
    addDeviceFactory(devicesFactory, false /*needToNotify*/);
}

//这个方法将那些HAL模块存入mDeviceFactories
void DevicesFactoryHalHidl::addDeviceFactory(sp<IDevicesFactory> factory, bool needToNotify) {
    // It is assumed that the DevicesFactoryHalInterface instance is owned
    // by AudioFlinger and thus have the same lifespan.
    factory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
    sp<DevicesFactoryHalCallback> callback;
    {
        std::lock_guard<std::mutex> lock(mLock);
        mDeviceFactories.push_back(factory);
        ALOGE("HIDL---------------addDeviceFactory factory");
        if (needToNotify) {
            callback = mCallback.promote();
            if (!callback) {
                mHaveUndeliveredNotifications = true;
            }
        }
    }
    if (callback) {
        callback->onNewDevicesAvailable();
    }
}

//这个主要是服务起来时,创建了一个监听
void DevicesFactoryHalHidl::onFirstRef() {
    sp<IServiceManager> sm = IServiceManager::getService();
    ALOG_ASSERT(sm != nullptr, "Hardware service manager is not running");
    ALOGE("HIDL---------------DevicesFactoryHalHidl::onFirstRef-----------");
    sp<ServiceNotificationListener> listener = new ServiceNotificationListener(this);
    Return<bool> result = sm->registerForNotifications(
            IDevicesFactory::descriptor, "", listener);
    if (result.isOk()) {
        ALOGE_IF(!static_cast<bool>(result),
                "Hardware service manager refused to register listener");
        ALOGE("HIDL------Register for hardware service manager notifications: %s",
                result.description().c_str());        
    } else {
        ALOGE("Failed to register for hardware service manager notifications: %s",
                result.description().c_str());
    }
}

#if MAJOR_VERSION == 2
static IDevicesFactory::Device idFromHal(const char *name, status_t* status) {
    *status = OK;
    ALOGE("HIDL------idFromHal device name %s", name);
    if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
        return IDevicesFactory::Device::PRIMARY;
    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) {
        return IDevicesFactory::Device::A2DP;
    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) {
        return IDevicesFactory::Device::USB;
    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) == 0) {
        return IDevicesFactory::Device::R_SUBMIX;
    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_STUB) == 0) {
        return IDevicesFactory::Device::STUB;
    }
    ALOGE("Invalid device name %s", name);
    *status = BAD_VALUE;
    return {};
}
#elif MAJOR_VERSION >= 4
static const char* idFromHal(const char *name, status_t* status) {
    *status = OK;
    return name;
}
#endif

status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    auto factories = copyDeviceFactories();
    ALOGE("HIDL---------openDevice device name %s", name);
    if (factories.empty()) return NO_INIT;
    status_t status;
    //hidlId ,这个看情况,如果是MAJOR_VERSION>4就是name,如果不是见MAJOR_VERSION == 2时的idFromHal
    auto hidlId = idFromHal(name, &status);
    if (status != OK) return status;
    Result retval = Result::NOT_INITIALIZED;
    //factories包含所有的HAL模块primary、bluetooth、usb
    for (const auto& factory : factories) {
    	//这个factory->openDevice里面就实现了一个回调,这个回调获取到的Result跟result就是DevicesFactory中的openDevice中的内容,这里实现的就是那里的回调
        Return<void> ret = factory->openDevice(
                hidlId,
                //这里的r和result就是3.3中的回调得到的值
                [&](Result r, const sp<IDevice>& result) {
                    retval = r;
                    if (retval == Result::OK) {
                    	//这个主要是创建一个远程代理,可以通过传入实例化的result,实例化一个device去操作HAL层的方法
                    	//这个通过这个在DeviceHalHidl定义了很多HAL层相关的方法,通过远程代理result,就可以去操作HAL方法了
						//需要注意的是,将回调得到的result作为构造的传入参数,result是一个具体的HAL设备,例如:MTKPrimaryDevice这些HAL模块
						//稍后,我们会对DeviceHalHidl进行详细的分析。
                        *device = new DeviceHalHidl(result);
                        //从这里,就从拿到了对应的HAL接口,注意device是一个传入传出参数
                    }
                });
        if (!ret.isOk()) return FAILED_TRANSACTION;
        switch (retval) {
            // Device was found and was initialized successfully.
            case Result::OK: return OK;
            // Device was found but failed to initalize.
            case Result::NOT_INITIALIZED: return NO_INIT;
            // Otherwise continue iterating.
            default: ;
        }
    }
    ALOGW("The specified device name is not recognized: \"%s\"", name);
    return BAD_VALUE;
}

std::vector<sp<IDevicesFactory>> DevicesFactoryHalHidl::copyDeviceFactories() {
    std::lock_guard<std::mutex> lock(mLock);
    return mDeviceFactories;
}

} // namespace CPP_VERSION
} // namespace android

2.5 DeviceHalHidl.cpp

这里,我们只拿出几个方法进行说明

//注意这个mDevice、mPrimaryDevice参数
DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
        : ConversionHelperHidl("Device"), mDevice(device),
          mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
}
//只需关注mDevice,以及这些方法里面做了什么操作即可,这里不具体分析
status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
    if (mDevice == 0) return NO_INIT;
    hidl_vec<ParameterValue> hidlParams;
    status_t status = parametersFromHal(kvPairs, &hidlParams);
    if (status != OK) return status;
    // TODO: change the API so that context and kvPairs are separated
    return processReturn("setParameters",
                         utils::setParameters(mDevice, {} /* context */, hidlParams));
}
//只需关注mDevice,以及这些方法里面做了什么操作即可,这里不具体分析
status_t DeviceHalHidl::getInputBufferSize(
        const struct audio_config *config, size_t *size) {
    if (mDevice == 0) return NO_INIT;
    AudioConfig hidlConfig;
    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
    Result retval;
    //这里实现了回调
    Return<void> ret = mDevice->getInputBufferSize(
            hidlConfig,
            [&](Result r, uint64_t bufferSize) {
                retval = r;
                if (retval == Result::OK) {
                    *size = static_cast<size_t>(bufferSize);
                }
            });
    return processReturn("getInputBufferSize", ret, retval);
}
//只需关注mDevice,以及这些方法里面做了什么操作即可,这里不具体分析
status_t DeviceHalHidl::openOutputStream(
        audio_io_handle_t handle,
        audio_devices_t deviceType,
        audio_output_flags_t flags,
        struct audio_config *config,
        const char *address,
        sp<StreamOutHalInterface> *outStream) {
    if (mDevice == 0) return NO_INIT;
    DeviceAddress hidlDevice;
    status_t status = deviceAddressFromHal(deviceType, address, &hidlDevice);
    if (status != OK) return status;
    AudioConfig hidlConfig;
    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
    Result retval = Result::NOT_INITIALIZED;
    Return<void> ret = mDevice->openOutputStream(
            handle,
            hidlDevice,
            hidlConfig,
            EnumBitfield<AudioOutputFlag>(flags),
#if MAJOR_VERSION >= 4
            {} /* metadata */,
#endif
            [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
                retval = r;
                if (retval == Result::OK) {
                    *outStream = new StreamOutHalHidl(result);
                }
                HidlUtils::audioConfigToHal(suggestedConfig, config);
            });
    return processReturn("openOutputStream", ret, retval);
}
//只需关注mDevice,以及这些方法里面做了什么操作即可,这里不具体分析
status_t DeviceHalHidl::openInputStream(
        audio_io_handle_t handle,
        audio_devices_t devices,
        struct audio_config *config,
        audio_input_flags_t flags,
        const char *address,
        audio_source_t source,
        audio_devices_t outputDevice,
        const char *outputDeviceAddress,
        sp<StreamInHalInterface> *inStream) {
    if (mDevice == 0) return NO_INIT;
    DeviceAddress hidlDevice;
    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
    if (status != OK) return status;
    AudioConfig hidlConfig;
    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
    Result retval = Result::NOT_INITIALIZED;
#if MAJOR_VERSION == 2
    auto sinkMetadata = AudioSource(source);
#elif MAJOR_VERSION >= 4
    // TODO: correctly propagate the tracks sources and volume
    //       for now, only send the main source at 1dbfs
    SinkMetadata sinkMetadata = {{{ .source = AudioSource(source), .gain = 1 }}};
#endif
#if MAJOR_VERSION < 5
    (void)outputDevice;
    (void)outputDeviceAddress;
#else
    if (outputDevice != AUDIO_DEVICE_NONE) {
        DeviceAddress hidlOutputDevice;
        status = deviceAddressFromHal(outputDevice, outputDeviceAddress, &hidlOutputDevice);
        if (status != OK) return status;
        sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
    }
#endif
#if MAJOR_VERSION <= 5
    // Some flags were specific to framework and must not leak to the HAL.
    flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
#endif
    Return<void> ret = mDevice->openInputStream(
            handle,
            hidlDevice,
            hidlConfig,
            EnumBitfield<AudioInputFlag>(flags),
            sinkMetadata,
            [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
                retval = r;
                if (retval == Result::OK) {
                    *inStream = new StreamInHalHidl(result);
                }
                HidlUtils::audioConfigToHal(suggestedConfig, config);
            });
    return processReturn("openInputStream", ret, retval);
}

这里,先总结一下上面的代码,主要做了什么事情:
1.AudioFlinger中创建mDevicesFactoryHal 接口
2.FactoryHalHidl中通过打开libaudiohal@6.0.so库,获取库中的方法createIDevicesFactory的handle
3.当2的createIDevicesFactory handle被使用时,实例化了DevicesFactoryHalHybrid这个类
4.当AudioFlinger调用mDevicesFactoryHal->openDevice(name, &dev)时,实际时调用到DevicesFactoryHalHidl(或DevicesFactoryHalLocal)中的oepnDevice(const char *name, sp *device)
5.DevicesFactoryHalHidl中的oepnDevice有一个回调的实现factory->openDevice(){callback…},有关factory的分析,我们在第三节中会详细的分析,先知道这个回调得到的是什么内容,这个设备将会在第三节分析。

//Result r, const sp<IDevice>& result
//r是一个状态返回值,主要用于判断服务是否获取/创建成功,result是一个代理/接口,用来操作底层的HAL
[&](Result r, const sp<IDevice>& result) {*device = new DeviceHalHidl(result);}

三、HAL层接口分析

下面将围绕这张图进行分析
在这里插入图片描述

还记得2.3小节中的createIDevicesFactory方法吗?这个方法实际上就是获取IDevicesFactory的服务,并将这个服务接口传入,现在,我们分析IDevicesFactory这个服务是怎么回事

extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
    auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
    return service ? new CPP_VERSION::DevicesFactoryHalHybrid(service) : nullptr;
}
--------------------------------------------
# ps -A | grep "android.hardware.audio.service.mediatek"
audioserver     485      1   57180  25776 binder_ioctl_write_read 0 S android.hardware.audio.service.mediatek

3.1 android.hardware.audio.service.mediatek.rc

找到路径vendor/mediatek/proprietary/hardware/audio/common/service/6.0/(这个路径看具体情况,不同厂商存放路径有差异,根据实际情况确定),在这里路径里包含了一个rc文件

on post-fs-data
    mkdir /data/vendor/audiohal 0771 system audio			
//这个就是要启动的服务,可以ps -A | grep mediatek,看一下能不能找到这个服务
service vendor.audio-hal /vendor/bin/hw/android.hardware.audio.service.mediatek
    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 system sdcard_rw
    capabilities BLOCK_SUSPEND SYS_NICE
    ioprio rt 4
    task_profiles ProcessCapacityHigh HighPerformance

-----------------------------------------------------------------------------------------
admin:/ # ps -A | grep "android.hardware.audio.service.mediatek"
audioserver    2662      1   52692  26068 binder_ioctl_write_read 0 S android.hardware.audio.service.mediatek

3.2下面分析上述rc文件启动的这个服务service.cpp

//在这里,我们只分析一些比较重要的代码
int main(int /* argc */, char * /* argv */ []) {
    ALOGD("Start audiohalservice ++");
	......
	//这个就是注册这个服务类了,主要分析这个部分代码
    ALOGD("registering IDevicesFactory");
    bool fail = registerPassthroughServiceImplementation<audio::V6_0::IDevicesFactory>() != OK;
    ALOGD("registered IDevicesFactory");
    LOG_ALWAYS_FATAL_IF(fail, "Could not register audio core API 6.0");

	//同上,不过这部分不分析
    ALOGD("registering IEffectsFactory");
    fail = registerPassthroughServiceImplementation<audio::effect::V6_0::IEffectsFactory>() != OK;
    ALOGD("registered IEffectsFactory");
    LOG_ALWAYS_FATAL_IF(fail, "Could not register audio effect API 6.0");


#ifdef MTK_A2DP_OFFLOAD_SUPPORT
    ALOGD("registering IBluetoothAudioOffload");
    // remove the old HIDL when Bluetooth Audio Hal V2 has offloading supported
    fail =
        registerPassthroughServiceImplementation<bluetooth::a2dp::V1_0::IBluetoothAudioOffload>() !=
        OK;
    ALOGD("registered IBluetoothAudioOffload");
    ALOGW_IF(fail, "Could not register Bluetooth audio offload 1.0");
#endif
    joinRpcThreadpool();
    ALOGD("Start audiohalservice --");
}

3.3 这里分析上述服务中注册的类DeviceFactory.cpp

#define LOG_TAG0 "DevicesFactoryHAL"
#define LOG_TAG "KK"

#include "DevicesFactory.h"
#include "Device.h"
//#include "PrimaryDevice.h"
#include "MTKPrimaryDevice.h"
#include <string.h>
#include <android/log.h>

namespace android {
namespace hardware {
namespace audio {
namespace CPP_VERSION {
namespace implementation {

Return<void> DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) {
    if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
        return openDevice<vendor::mediatek::hardware::audio::V6_1::implementation::MTKPrimaryDevice>(moduleName.c_str(), _hidl_cb);
    }
    return openDevice(moduleName.c_str(), _hidl_cb);
}
Return<void> DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) {
    return openDevice<vendor::mediatek::hardware::audio::V6_1::implementation::MTKPrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
}

Return<void> DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) {
    return openDevice<::android::hardware::audio::V6_0::implementation::Device>(moduleName, _hidl_cb);
}

//这个是重点分析的方法,注意,这个是一个模板方法,DeviceShim是模板类,Callback是一个回调,回调会返回一个结果值和一个模板来实例化后的对象
template <class DeviceShim, class Callback>
Return<void> DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
    audio_hw_device_mtk_t* halDevice;
    //这个是回调中将要返回的结果值
    Result retval(Result::INVALID_ARGUMENTS);
    //这个是回调中将要返回的模板实例化后的对象
    sp<DeviceShim> result;
    ALOGE("%s the moduleName %s ", __func__, moduleName);
    //这个方法主要是根据模块名为了获取一个halDevice,halDevice是一个传入传出参数,halDevice//**用于打开和关闭受支持设备的便捷API*/
    int halStatus = loadAudioInterface(moduleName, (audio_hw_device_t **)&halDevice);
    if (halStatus == OK) {
    	//这里就是使用了一个模板类去实现,halDevice是一个传入参数
    	//这里举例:模板类是MTKPrimaryDevice.cpp
        result = new DeviceShim(halDevice);	
        retval = Result::OK;
    } else if (halStatus == -EINVAL) {
        retval = Result::NOT_INITIALIZED;
    }
    //最后返回了一个结果值和模板类的实例化对象(例:MTKPrimaryDevice)
    //这个还需要联系到2.4小节中的openDevice方法中,回调的实现,这个result,就是一个实现类,
    //故2.5小节中DeviceHalHidl中所有的方法调用,result所调用的都是模板类的方法(例:MTKPrimaryDevice)
    _hidl_cb(retval, result);
    return Void();
}

// static
int DevicesFactory::loadAudioInterface(const char *if_name, audio_hw_device_t **dev) {
    const hw_module_t *mod;
    int rc;
	//hw_get_module_by_class这个方法是位于hardware/libhardware/hardware.c这个文件里
	//大致讲解这个方法的作用:
	//mod是传入传出参数,AUDIO_HARDWARE_MODULE_ID在这里是audio(还有其他),if_name是primary/bluetooth/usb
	//这个方法加载ro.hardware.audio.primary这个HAL的模块
	//如果存在就返回hw_module_t类型的primary模块handle
    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
    if (rc) {
        ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
              if_name, strerror(-rc));
        goto out;
    }
    ALOGE("%s could load audio hw module %s.%s", __func__, AUDIO_HARDWARE_MODULE_ID,
              if_name);
    //audio_hw_device_open这个方法在audio.h这个方法内
    //**用于打开和关闭受支持设备的便捷API*/
    //注意dev是一个传入传出参数
    //这个方法会在3.7节中讲解
    rc = audio_hw_device_open(mod, dev);
    if (rc) {
        ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
              if_name, strerror(-rc));
        goto out;
    }
    if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
        rc = -EINVAL;
        audio_hw_device_close(*dev);
        goto out;
    }
    ALOGE("%s audio hw device version %04x", __func__, (*dev)->common.version);
    return OK;

out:
    *dev = NULL;
    return rc;
}
//上述服务中注册的类,就是从这里注册的
IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name) {
    return strcmp(name, "default") == 0 ? new DevicesFactory() : nullptr;
}

}  // namespace implementation
}  // namespace CPP_VERSION
}  // namespace audio
}  // namespace hardware
}  // namespace android

3.4 MTKPrimaryDevice.cpp这个就是上述的模板之一

#define LOG_TAG "MTKPrimaryDeviceHAL"

#include "MTKPrimaryDevice.h"
#include "Util.h"

#include <cmath>

using ::android::hardware::audio::V6_0::implementation::isGainNormalized;

namespace vendor {
namespace mediatek {
namespace hardware {
namespace audio {
namespace V6_1 {
namespace implementation {
//3.3中传进去的halDevice,就是作为device这个参数去实例化一个Device,最后通过mDevice去操作HAL
MTKPrimaryDevice::MTKPrimaryDevice(audio_hw_device_mtk_t *device)
    : mDevice(new android::hardware::audio::V6_0::implementation::Device(device)) {}

MTKPrimaryDevice::~MTKPrimaryDevice() {
    // Do not call mDevice->close here. If there are any unclosed streams,
    // they only hold IDevice instance, not IPrimaryDevice, thus IPrimaryDevice
    // "part" of a device can be destroyed before the streams.
}

//有下面几个方法可以知道MTKPrimaryDevice类似于一个中间件,下层连接HAL层,上层连接SERVICE层
Return<void> MTKPrimaryDevice::getInputBufferSize(const AudioConfig &config,
                                               getInputBufferSize_cb _hidl_cb) {
    return mDevice->getInputBufferSize(config, _hidl_cb);
}

Return<void> MTKPrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
                                             const AudioConfig& config,
                                             AudioOutputFlagBitfield flags,
                                             const SourceMetadata& sourceMetadata,
                                             openOutputStream_cb _hidl_cb) {
    return mDevice->openOutputStream(ioHandle, device, config, flags, sourceMetadata, _hidl_cb);
}

Return<void> MTKPrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device,
                                            const AudioConfig& config, AudioInputFlagBitfield flags,
                                            const SinkMetadata& sinkMetadata,
                                            openInputStream_cb _hidl_cb) {
    return mDevice->openInputStream(ioHandle, device, config, flags, sinkMetadata, _hidl_cb);
}

Return<void> MTKPrimaryDevice::getParameters(const hidl_vec<ParameterValue>& context,
                                          const hidl_vec<hidl_string>& keys,
                                          getParameters_cb _hidl_cb) {
    return mDevice->getParameters(context, keys, _hidl_cb);
}
Return<Result> MTKPrimaryDevice::setParameters(const hidl_vec<ParameterValue>& context,
                                            const hidl_vec<ParameterValue>& parameters) {
    return mDevice->setParameters(context, parameters);
}

Return<Result> MTKPrimaryDevice::close() {
    return mDevice->close();
}
}  // namespace implementation
}  // namespace V6_1
}  // namespace audio
}  // namespace hardware
}  // namespace mediatek
}  // namespace vendor

3.5 Device.cpp

#define LOG_TAG "DeviceHAL"
......
namespace android {
namespace hardware {
namespace audio {
namespace CPP_VERSION {
namespace implementation {
// For callback processing, keep the device sp list to avoid device be free by system
static Vector<sp<Device>> gCallbackDeviceList;

using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;

Device::Device(audio_hw_device_mtk_t* device) : mIsClosed(false), mDevice(device) {}

Device::~Device() {
    ALOGD("%s ++, doClose()", __func__);
    (void)doClose();
    mDevice = nullptr;
    ALOGD("%s --", __func__);
}

void Device::closeInputStream(audio_stream_in_t *stream) {
    ALOGD("%s mOpenedStreamsCount %d", __func__, mOpenedStreamsCount);
    mDevice->close_input_stream(mDevice, stream);
    LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "closeInputStream mOpenedStreamsCount is already 0");
    --mOpenedStreamsCount;
}

void Device::closeOutputStream(audio_stream_out_t *stream) {
    ALOGD("%s mOpenedStreamsCount %d", __func__, mOpenedStreamsCount);
    mDevice->close_output_stream(mDevice, stream);
    LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "closeOutputStream mOpenedStreamsCount is already 0");
    --mOpenedStreamsCount;
}

// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow.
Return<Result> Device::initCheck() {
    return analyzeStatus("init_check", mDevice->init_check(mDevice));
}


Return<void> Device::getInputBufferSize(const AudioConfig &config, getInputBufferSize_cb _hidl_cb) {
    audio_config_t halConfig;
    HidlUtils::audioConfigToHal(config, &halConfig);
    size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig);
    Result retval(Result::INVALID_ARGUMENTS);
    uint64_t bufferSize = 0;
    if (halBufferSize != 0) {
        retval = Result::OK;
        bufferSize = halBufferSize;
    }
    _hidl_cb(retval, bufferSize);
    return Void();
}

std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle,
                                                                const DeviceAddress& device,
                                                                const AudioConfig& config,
                                                                AudioOutputFlagBitfield flags,
                                                                AudioConfig* suggestedConfig) {
    audio_config_t halConfig;
    HidlUtils::audioConfigToHal(config, &halConfig);
    audio_stream_out_t *halStream;
    ALOGV(
        "open_output_stream handle: %d devices: %x flags: %#x "
        "srate: %d format %#x channels %x address %s",
        ioHandle, static_cast<audio_devices_t>(device.device),
        static_cast<audio_output_flags_t>(flags), halConfig.sample_rate, halConfig.format,
        halConfig.channel_mask, deviceAddressToHal(device).c_str());
    int status =
        mDevice->open_output_stream(mDevice, ioHandle, static_cast<audio_devices_t>(device.device),
                     static_cast<audio_output_flags_t>(flags), &halConfig,
                     &halStream, deviceAddressToHal(device).c_str());
    ALOGV("open_output_stream status %d stream %p", status, halStream);
    sp<IStreamOut> streamOut;
    if (status == OK) {
        streamOut = new StreamOut(this, halStream);
        ++mOpenedStreamsCount;
        ALOGD("%s, flags: %#x, open_output_stream success, mOpenedStreamsCount %d",
              __func__, static_cast<audio_output_flags_t>(flags), mOpenedStreamsCount);
    } else {
        ALOGD("%s, flags: %#x, open_output_stream fail, mOpenedStreamsCount %d",
              __func__, static_cast<audio_output_flags_t>(flags), mOpenedStreamsCount);
    }

    status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
    ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
    return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
}

std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl(
    int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
    AudioInputFlagBitfield flags, AudioSource source, AudioConfig* suggestedConfig) {
    audio_config_t halConfig;
    HidlUtils::audioConfigToHal(config, &halConfig);
    audio_stream_in_t *halStream;
    ALOGV(
        "open_input_stream handle: %d devices: %x flags: %#x "
        "srate: %d format %#x channels %x address %s source %d",
        ioHandle, static_cast<audio_devices_t>(device.device),
        static_cast<audio_input_flags_t>(flags), halConfig.sample_rate, halConfig.format,
        halConfig.channel_mask, deviceAddressToHal(device).c_str(),
        static_cast<audio_source_t>(source));
    int status = mDevice->open_input_stream(
                     mDevice, ioHandle, static_cast<audio_devices_t>(device.device), &halConfig, &halStream,
                     static_cast<audio_input_flags_t>(flags), deviceAddressToHal(device).c_str(),
                     static_cast<audio_source_t>(source));
    ALOGV("open_input_stream status %d stream %p", status, halStream);
    sp<IStreamIn> streamIn;
    if (status == OK) {
        streamIn = new StreamIn(this, halStream);
        ++mOpenedStreamsCount;
        ALOGD("%s, flags: %#x, open_input_stream success, mOpenedStreamsCount %d",
              __func__, static_cast<audio_input_flags_t>(flags), mOpenedStreamsCount);
    } else {
        ALOGD("%s, flags: %#x, open_input_stream fail, mOpenedStreamsCount %d",
              __func__, static_cast<audio_input_flags_t>(flags), mOpenedStreamsCount);
    }

    status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
    ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
    return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
}

Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
                                      const AudioConfig& config, AudioOutputFlagBitfield flags,
                                      const SourceMetadata& sourceMetadata,
                                      openOutputStream_cb _hidl_cb) {
    AudioConfig suggestedConfig;
    auto [result, streamOut] =
        openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig);
    if (streamOut) {
        streamOut->updateSourceMetadata(sourceMetadata);
    }
    _hidl_cb(result, streamOut, suggestedConfig);
    return Void();
}

Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
                                     const AudioConfig& config, AudioInputFlagBitfield flags,
                                     const SinkMetadata& sinkMetadata,
                                     openInputStream_cb _hidl_cb) {
    if (sinkMetadata.tracks.size() == 0) {
        // This should never happen, the framework must not create as stream
        // if there is no client
        ALOGE("openInputStream called without tracks connected");
        _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, AudioConfig());
        return Void();
    }
    // Pick the first one as the main.
    AudioSource source = sinkMetadata.tracks[0].source;
    AudioConfig suggestedConfig;
    auto [result, streamIn] =
        openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig);
    if (streamIn) {
        streamIn->updateSinkMetadata(sinkMetadata);
    }
    _hidl_cb(result, streamIn, suggestedConfig);
    return Void();
}


Return<void> Device::getParameters(const hidl_vec<ParameterValue>& context,
                                   const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
    getParametersImpl(context, keys, _hidl_cb);
    return Void();
}
Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& context,
                                     const hidl_vec<ParameterValue>& parameters) {
    return setParametersImpl(context, parameters);
}

}  // namespace implementation
}  // namespace CPP_VERSION
}  // namespace audio
}  // namespace hardware
}  // namespace android

第三小节总的来说,做了以下分析:
1.启动一个服务server,这个服务注册IDevicesFactory
2.然后第二小节中通过获取这个服务,调用DevicesFactory里的方法
3.调用openDevice方法
4.通过模板类可以实现对多葛HAL模块的操作
5.最后openDevice传出的dev参数,具体操作是通过Device去远程调用对应的hal模块中方法,这个会在下一节进行讨论

3.6 关于Device.cpp中传入的参数audio_hw_device_mtk_t的分析

audio_hw_device_mtk_t.h如下所示

#ifndef ANDROID_AUDIO_HAL_INTERFACE_MTK_H
#define ANDROID_AUDIO_HAL_INTERFACE_MTK_H
#define AUDIO_PARAMETER_KEY_TIME_STRETCH "time_stretch"
#define AUDIO_PARAMETER_KEY_HDMI_BITWIDCH "HDMI_bitwidth"
#define AUDIO_PARAMETER_KEY_HDMI_CHANNEL "HDMI_channel"
#define AUDIO_PARAMETER_KEY_HDMI_MAXSAMPLERATE "HDMI_maxsamplingrate"
#define AUDIO_PARAMETER_KEY_BESSURROUND_ONOFF "BesSurround_OnOff"
#define AUDIO_PARAMETER_KEY_BESSURROUND_MODE "BesSurround_Mode"
#define AUDIO_PARAMETER_KEY_HDMI_MAXSAMPLERATE "HDMI_maxsamplingrate"
#define AUDIO_PARAMETER_KEY_BESSURROUND_ONOFF "BesSurround_OnOff"
#define AUDIO_PARAMETER_KEY_BESSURROUND_MODE "BesSurround_Mode"
#define AUDIO_PARAMETER_KEY_BESAUDEN_ONOFF "SetMusicPlusStatus"
#define AUDIO_PARAMETER_KEY_ROUTING_TO_NONE "ROUTING_TO_NONE"
#define AUDIO_PARAMETER_KEY_FM_DIRECT_CONTROL "FM_DIRECT_CONTROL"
//hardware/audio.h这个才是我们需要重点关注的头文件,这个是通用的
#include <hardware/audio.h>

typedef enum {
    DEVICE_CBK_EVENT_SETPARAMETERS,
} device_parameters_callback_event_t;

typedef struct audio_hw_device_set_parameters_callback {
    int paramchar_len;
    char paramchar[1024];
} audio_hw_device_set_parameters_callback_t;

typedef int (*device_parameters_callback_t)(device_parameters_callback_event_t event, audio_hw_device_set_parameters_callback_t *param, void *cookie);
typedef int (*device_audio_parameter_changed_callback_t)(const char *param, void *cookie);
//这些都是mtk的接口
struct audio_hw_device_mtk: audio_hw_device {
    int (*xway_play_start)(struct audio_hw_device *dev, int sample_rate);
    int (*xway_play_stop)(struct audio_hw_device *dev);
    int (*xway_play_write)(struct audio_hw_device *dev, void *buffer, int size_bytes);
    int (*xway_getfreebuffercount)(struct audio_hw_device *dev);
    int (*xway_rec_start)(struct audio_hw_device *dev, int smple_rate);
    int (*xway_rec_stop)(struct audio_hw_device *dev);
    int (*xway_rec_read)(struct audio_hw_device *dev, void *buffer, int size_bytes);
    int (*setup_parameters_callback)(struct audio_hw_device *dev, device_parameters_callback_t callback, void *cookie);
    int (*set_audio_parameter_changed_callback)(struct audio_hw_device *dev, device_audio_parameter_changed_callback_t callback, void *cookie);
    int (*clear_audio_parameter_changed_callback)(struct audio_hw_device *dev, void *cookie);
};
typedef struct audio_hw_device_mtk audio_hw_device_mtk_t;

#endif  // ANDROID_AUDIO_HAL_INTERFACE_MTK_H
-------------------------------------------------------------------------------------------------------------
//这里删除了大量的代码,只保留一些代码
//但是也可以看到这些接口是server层到HAL层的标准接口
#include <hardware/hardware.h>
#include <system/audio.h>
#include <hardware/audio_effect.h>
#define AUDIO_HARDWARE_MODULE_ID "audio"
#define AUDIO_HARDWARE_INTERFACE "audio_hw_if"
/**************************************/
/**
 *  standard audio parameters that the HAL may need to handle
 */
/**
 *  audio device parameters
 */
/* common audio stream parameters and operations */
struct audio_stream {
    uint32_t (*get_sample_rate)(const struct audio_stream *stream);
    int (*set_sample_rate)(struct audio_stream *stream, uint32_t rate);
    size_t (*get_buffer_size)(const struct audio_stream *stream);
    audio_channel_mask_t (*get_channels)(const struct audio_stream *stream);
    audio_format_t (*get_format)(const struct audio_stream *stream);
    int (*set_format)(struct audio_stream *stream, audio_format_t format);
    int (*standby)(struct audio_stream *stream);
    audio_devices_t (*get_device)(const struct audio_stream *stream);
    int (*set_device)(struct audio_stream *stream, audio_devices_t device);
    int (*set_parameters)(struct audio_stream *stream, const char *kv_pairs);
};
typedef struct audio_stream audio_stream_t;

/* type of asynchronous write callback events. Mutually exclusive */
typedef enum {
    STREAM_CBK_EVENT_WRITE_READY, /* non blocking write completed */
    STREAM_CBK_EVENT_DRAIN_READY,  /* drain completed */
    STREAM_CBK_EVENT_ERROR, /* stream hit some error, let AF take action */
} stream_callback_event_t;

typedef enum {
    STREAM_EVENT_CBK_TYPE_CODEC_FORMAT_CHANGED, /* codec format of the stream changed */
} stream_event_callback_type_t;

typedef int (*stream_callback_t)(stream_callback_event_t event, void *param, void *cookie);

typedef int (*stream_event_callback_t)(stream_event_callback_type_t event,
                                       void *param, void *cookie);

/* type of drain requested to audio_stream_out->drain(). Mutually exclusive */
typedef enum {
    AUDIO_DRAIN_ALL,            /* drain() returns when all data has been played */
    AUDIO_DRAIN_EARLY_NOTIFY    /* drain() returns a short time before all data
                                   from the current track has been played to
                                   give time for gapless track switch */
} audio_drain_type_t;

typedef struct source_metadata {
    size_t track_count;
    /** Array of metadata of each track connected to this source. */
    struct playback_track_metadata* tracks;
} source_metadata_t;

typedef struct sink_metadata {
    size_t track_count;
    /** Array of metadata of each track connected to this sink. */
    struct record_track_metadata* tracks;
} sink_metadata_t;

struct audio_stream_out {
    struct audio_stream common;
    int (*set_volume)(struct audio_stream_out *stream, float left, float right);
    ssize_t (*write)(struct audio_stream_out *stream, const void* buffer,
                     size_t bytes);
    int (*set_callback)(struct audio_stream_out *stream,
            stream_callback_t callback, void *cookie);
    int (*pause)(struct audio_stream_out* stream);
    int (*start)(const struct audio_stream_out* stream);
    int (*stop)(const struct audio_stream_out* stream);
    int (*create_mmap_buffer)(const struct audio_stream_out *stream,
                              int32_t min_size_frames,
                              struct audio_mmap_buffer_info *info);
};
typedef struct audio_stream_out audio_stream_out_t;

struct audio_stream_in {
    struct audio_stream common;
    ssize_t (*read)(struct audio_stream_in *stream, void* buffer,
                    size_t bytes);
    int (*start)(const struct audio_stream_in* stream);
    int (*stop)(const struct audio_stream_in* stream);
    int (*create_mmap_buffer)(const struct audio_stream_in *stream,
                              int32_t min_size_frames,
                              struct audio_mmap_buffer_info *info);
};
typedef struct audio_stream_in audio_stream_in_t;

/**********************************************************************/
struct audio_module {
    struct hw_module_t common;
};

struct audio_hw_device {
    struct hw_device_t common;
    uint32_t (*get_supported_devices)(const struct audio_hw_device *dev);
    int (*init_check)(const struct audio_hw_device *dev);
    int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs);
    int (*open_output_stream)(struct audio_hw_device *dev,
                              audio_io_handle_t handle,
                              audio_devices_t devices,
                              audio_output_flags_t flags,
                              struct audio_config *config,
                              struct audio_stream_out **stream_out,
                              const char *address);
    void (*close_output_stream)(struct audio_hw_device *dev,
                                struct audio_stream_out* stream_out);
    int (*open_input_stream)(struct audio_hw_device *dev,
                             audio_io_handle_t handle,
                             audio_devices_t devices,
                             struct audio_config *config,
                             struct audio_stream_in **stream_in,
                             audio_input_flags_t flags,
                             const char *address,
                             audio_source_t source);

    void (*close_input_stream)(struct audio_hw_device *dev,
                               struct audio_stream_in *stream_in);
};
typedef struct audio_hw_device audio_hw_device_t;

static inline int audio_hw_device_open(const struct hw_module_t* module,
                                       struct audio_hw_device** device)
{
	// 注意:module->methods->open执行的是audio_hw_hal.cpp中的legacy_adev_open!!!
	//这个方法具体实现是在3.7小节中
	// 这是一个很重要的方法,在3.2小节的时候,就是用这个方法去打开设备的
    return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,
                                 TO_HW_DEVICE_T_OPEN(device));
}
__END_DECLS

#endif  // ANDROID_AUDIO_INTERFACE_H

3.7 HAL的接口audio_hw_hal.cpp

一般每一个Audio HAL设备都会有一个audio_hw_hal.cpp文件

	//这是一个很重要的结构体
	struct legacy_audio_device {
        struct audio_hw_device_mtk device;
        AudioMTKHardwareInterface *hwif;		//这个变量非常重要,它可以调用很多HAL方法
    };
    
    //这个类中的一些方法(例子)
    static int adev_init_check(const struct audio_hw_device *dev) {
#ifdef AUDIO_HAL_PROFILE_ENTRY_FUNCTION
        AudioAutoTimeProfile _p(__func__);
#endif
        const struct legacy_audio_device *ladev = to_cladev(dev);
        return ladev->hwif->initCheck();
    }
    //例子
    static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) {
#ifdef AUDIO_HAL_PROFILE_ENTRY_FUNCTION
        AudioAutoTimeProfile _p(__func__);
#endif
        struct legacy_audio_device *ladev = to_ladev(dev);
        return ladev->hwif->setParameters(String8(kvpairs));
    }
    
    //这是一个很重要的方法
    static int legacy_adev_open(const hw_module_t *module, const char *name,
                                hw_device_t **device) {
#ifdef AUDIO_HAL_PROFILE_ENTRY_FUNCTION
        char value[PROPERTY_VALUE_MAX];
        property_get("vendor.audio.hal.callstack", value, "0");
        AudioAutoTimeProfile::mDumpStack = atoi(value);
        AudioAutoTimeProfile _p(__func__);
#endif
		//注意这个参数legacy_audio_device *ladev,等会这个参数会跟具体的HAL相关
        struct legacy_audio_device *ladev;
        int ret;

        if (strncmp(name, AUDIO_HARDWARE_INTERFACE, strlen(AUDIO_HARDWARE_INTERFACE) + 1) != 0) {
            return -EINVAL;
        }

        ladev = (struct legacy_audio_device *)calloc(1, sizeof(*ladev));
        if (!ladev) {
            return -ENOMEM;
        }
		//加载一堆HAL层的方法,这些方法,也在该类中,不过这里不具体讨论
        ladev->device.common.tag = HARDWARE_DEVICE_TAG;
        ladev->device.common.module = const_cast<hw_module_t *>(module);
        ladev->device.common.close = legacy_adev_close;
        ladev->device.get_supported_devices = adev_get_supported_devices;
        ladev->device.init_check = adev_init_check;
        ladev->device.set_parameters = adev_set_parameters;
        ladev->device.get_parameters = adev_get_parameters;
        ladev->device.get_input_buffer_size = adev_get_input_buffer_size;
        ladev->device.open_output_stream = adev_open_output_stream;
        ladev->device.close_output_stream = adev_close_output_stream;
        ladev->device.open_input_stream = adev_open_input_stream;
        ladev->device.close_input_stream = adev_close_input_stream;
        ladev->device.xway_play_start = adev_xway_play_start;
        ladev->device.xway_play_stop = adev_xway_play_stop;
        ladev->device.xway_play_write = adev_xway_play_write;
        ladev->device.xway_getfreebuffercount = adev_xway_getfreebuffercount;
        ladev->device.xway_rec_start = adev_xway_rec_start;
        ladev->device.xway_rec_stop = adev_xway_rec_stop;
        ladev->device.xway_rec_read = adev_xway_rec_read;
        // added for HIDL extend
        ladev->device.setup_parameters_callback = adev_setup_parameters_callback;
        ladev->device.set_audio_parameter_changed_callback = adev_set_audio_parameters_changed_callback;
        ladev->device.clear_audio_parameter_changed_callback = adev_clear_audio_parameters_changed_callback;
        pthread_mutex_lock(&gHwInstanceLock);
        //注意这个方法,这个方法是AudioALSAHardwar.cpp中所创建,如下所示
        /*
        AudioMTKHardwareInterface *AudioMTKHardwareInterface::create() {
    		AudioMTKHardwareInterface *hw = 0;
    		char value[PROPERTY_VALUE_MAX];
    		ALOGV("Creating MTK AudioHardware");
   			hw = android::AudioALSAHardware::GetInstance();
    		return hw;
		}
		extern "C" AudioMTKHardwareInterface *createMTKAudioHardware() {
    		return AudioMTKHardwareInterface::create();
    	}
        */
        ladev->hwif = createMTKAudioHardware();
        if (!ladev->hwif) {
            pthread_mutex_unlock(&gHwInstanceLock);
            ret = -EIO;
            free(ladev);
            return ret;
        } else {
            gAudioHALRefCountByClient++;
            ALOGD("gAudioHALRefCountByClient + %d", gAudioHALRefCountByClient);
            pthread_mutex_unlock(&gHwInstanceLock);
        }
        *device = &ladev->device.common;
        return 0;
    }

	//
    static struct hw_module_methods_t legacy_audio_module_methods = {
        .open = legacy_adev_open
    };

    struct legacy_audio_module HAL_MODULE_INFO_SYM = {
        .module = {
            .common = {
                .tag = HARDWARE_MODULE_TAG,
                .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
                .hal_api_version = HARDWARE_HAL_API_VERSION,
                .id = AUDIO_HARDWARE_MODULE_ID,
                .name = "MTK Audio HW HAL",
                .author = "MTK",
                .methods = &legacy_audio_module_methods,
                .dso = NULL,
                .reserved = {0},
            },
        },
    };

总结

以上就是Audio server层到Audio HAL层的接口分析,如有错误,欢迎指正,谢谢!
下一篇将分析AudioHal层的代码,主要分析MTK的AudioALSA!

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值