提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一.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!