Android Q Audio 自上而下的调用逻辑和各模块相关初始化(AudioFlinger通信、Audio hal 加载、AudioDevice 选择)
随手笔记系列,内容较多较繁琐,用于结合目录快速查询
本文将通过AudioManger的setMastermute Api的通信传递实现逻辑,自上而下梳理一下调用顺序和各模块相关初始化,最终到的audio_hw.c来实现静音
文章目录
三、openHwDevice打开硬件设备
3.1 audioserver loadHwMoudle
3.1.1 AudioPolicyServicec初始化
首先在AudioServer启动时,AudioPolicyService进行初始化
//Main_audioserver
int main(int argc __unused, char **argv)
{
AudioPolicyService::instantiate();
}
instantiate()逻辑与AudioFlinger一样,详见2.1.2。所以现在直接看AudioPolicyService的构造函数,和onFirstRef();
AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
{
}
void AudioPolicyService::onFirstRef()
{
{
Mutex::Autolock _l(mLock);
//启动 audioCommand线程
// start audio commands thread
mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
//启动outputCommand线程
// start output activity command thread
mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
//初始化AudioPolicyClient 用于和af通信
mAudioPolicyClient = new AudioPolicyClient(this);
//创建AudioPolicyManager 把 mAudioPolicyClient传入
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
}
// load audio processing modules
sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
{
Mutex::Autolock _l(mLock);
mAudioPolicyEffects = audioPolicyEffects;
}
mUidPolicy = new UidPolicy(this);
mUidPolicy->registerSelf();
mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
mSensorPrivacyPolicy->registerSelf();
}
3.1.2 AudioPolicyManager初始化
AudioPolicyManger有多个 分为vendor 目录下的 managerdefault目录下的
vendor为厂商自己定义的,managerdefault目录为原生默认,接下来以原生为主
先看mk
LOCAL_SRC_FILES:= \
AudioPolicyFactory.cpp
LOCAL_SHARED_LIBRARIES := \
libaudiopolicymanagerdefault
LOCAL_MODULE:= libaudiopolicymanager
AudioPolicyFactory.h
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
return new AudioPolicyManager(clientInterface);
}
AudioPolicyManager
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
: AudioPolicyManager(clientInterface, false /*forTesting*/)
{
//解析audio_policy_configuration.xml
loadConfig();
//hwModule 加载 output input device初始化 等
initialize();
}
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
bool /*forTesting*/)
:
mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.
mpClientInterface(clientInterface),
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false),
//初始化 mHwModulesAll
mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice),
mAudioPortGeneration(1),
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
mBeaconMuted(false),
mTtsOutputAvailable(false),
mMasterMono(false),
mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
}
这次主要看hwModule加载
loadConfig(); 通过解析XML,得到不同的Moudle 放入mHwModulesAll集合里
解析过程代码太多可以看Serializer.cpp (f:\q\frameworks\av\services\audiopolicy\common\managerdefinitions\src)
#define AUDIO_HARDWARE_MODULE_ID_PRIMARY "primary"
#define AUDIO_HARDWARE_MODULE_ID_A2DP "a2dp"
#define AUDIO_HARDWARE_MODULE_ID_USB "usb"
#define AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX "r_submix"
#define AUDIO_HARDWARE_MODULE_ID_CODEC_OFFLOAD "codec_offload"
#define AUDIO_HARDWARE_MODULE_ID_STUB "stub"
#define AUDIO_HARDWARE_MODULE_ID_HEARING_AID "hearing_aid"
#define AUDIO_HARDWARE_MODULE_ID_MSD "msd"
在initialize里初始化 loadHwMoudle 循环打开loadHwModule
status_t AudioPolicyManager::initialize() {
for (const auto& hwModule : mHwModulesAll) {
hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
ALOGW("could not open HW module %s", hwModule->getName());
continue;
}
······
}
3.1.3 mpClientInterface->loadHwModule
mpClientInterface为之前传入的AudioPolicyClient
//AudioPolicyClientImpl.cpp (f:\q\frameworks\av\services\audiopolicy\service)
audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
//再次看到 AudioSystem::get_audio_flinger()
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
ALOGW("%s: could not get AudioFlinger", __func__);
return AUDIO_MODULE_HANDLE_NONE;
}
return af->loadHwModule(name);
}
:get_audio_flinger()逻辑详见2.1.3 AudioFlinger的获取
最后为AudioFlinger的 loadHwModule方法
3.1.4 AudioFlinger loadHwModule
audio_module_handle_t AudioFlinger::loadHwModule(const char *name){
return loadHwModule_l(name);
}
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
//防止重复load
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
ALOGW("loadHwModule() module %s already loaded", name);
return mAudioHwDevs.keyAt(i);
}
}
sp<DeviceHalInterface> dev;
//openDevice
int rc = mDevicesFactoryHal->openDevice(name, &dev);
if (rc) {
ALOGE("loadHwModule() error %d loading module %s", rc, name);
return AUDIO_MODULE_HANDLE_NONE;
}
mHardwareStatus = AUDIO_HW_INIT;
rc = dev->initCheck();
mHardwareStatus = AUDIO_HW_IDLE;
if (rc) {
ALOGE("loadHwModule() init check error %d for module %s", rc, name);
return AUDIO_MODULE_HANDLE_NONE;
}
//初始化flags
AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
{ // scope for auto-lock pattern
AutoMutex lock(mHardwareLock);
//获取device的 volume和mute状态
if (0 == mAudioHwDevs.size()) {
mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
float mv;
if (OK == dev->getMasterVolume(&mv)) {
mMasterVolume = mv;
}
mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
bool mm;
if (OK == dev->getMasterMute(&mm)) {
mMasterMute = mm;
}
}
mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
if (OK == dev->setMasterVolume(mMasterVolume)) {
flags = static_cast<AudioHwDevice::Flags>(flags |
AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
}
mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
if (OK == dev->setMasterMute(mMasterMute)) {
flags = static_cast<AudioHwDevice::Flags>(flags |
AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
}
mHardwareStatus = AUDIO_HW_IDLE;
}
if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
// An MSD module is inserted before hardware modules in order to mix encoded streams.
flags = static_cast<AudioHwDevice::Flags>(flags | AudioHwDevice::AHWD_IS_INSERT);
}
// flag 是 音量和静音状态
//其中handle的值是由nextUniqueId生成的,这样做保证了这个audiointerface拥有全局唯一的id号。
//添加到mAudioHwDevs里
audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
ALOGI("loadHwModule() Loaded %s audio interface, handle %d", name, handle);
return handle;
}
3.1.5 对libAudioHal返回的device add进mAudioHwDevs的维护
在loadHwModule最后会 将拿到的dev handle name flag作为参数,创建AudioHwDevice,最后加入到mAudioHwDevs里
audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
dev是hal层DeviceHalInterface类型的指针
name是moudle的名字
handle是通过nextUniqueId生成的唯一id 用作 key值来查询
flags是当前device的volume mute等信息
创建AudioHwDevice
class AudioHwDevice {
public:
enum Flags {
AHWD_CAN_SET_MASTER_VOLUME = 0x1,
AHWD_CAN_SET_MASTER_MUTE = 0x2,
// Means that this isn't a terminal module, and software patches
// are used to transport audio data further.
AHWD_IS_INSERT = 0x4,
};
AudioHwDevice(audio_module_handle_t handle,
const char *moduleName,
sp<DeviceHalInterface> hwDevice,
Flags flags)
: mHandle(handle)
, mModuleName(strdup(moduleName))
, mHwDevice(hwDevice)
, mFlags(flags) { }
AudioHwDevice提供的方法
bool canSetMasterVolume() const {
return (0 != (mFlags & AHWD_CAN_SET_MASTER_VOLUME));
}
bool canSetMasterMute() const {
return (0 != (mFlags & AHWD_CAN_SET_MASTER_MUTE));
}
bool isInsert() const {
return (0 != (mFlags & AHWD_IS_INSERT));
}
audio_module_handle_t handle() const { return mHandle; }
const char *moduleName() const { return mModuleName; }
//获取 DeviceHalInterface 指针
sp<DeviceHalInterface> hwDevice() const { return mHwDevice; }
status_t openOutputStream(
AudioStreamOut **ppStreamOut,
audio_io_handle_t handle,
audio_devices_t devices,
audio_output_flags_t flags,
struct audio_config *config,
const char *address);
bool supportsAudioPatches() const;
3.2 libAudioHal openDevice
3.2.1 libAudioHAL openDevice
mDevicesFactoryHal为之前DevicesFactoryHalInterface create
//DevicesFactoryHalHybrid.cpp
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);
}
//DevicesFactoryHalHidl.cpp
status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
if (mDeviceFactories.empty()) return NO_INIT;
status_t status;
auto hidlId = idFromHal(name, &status);
if (status != OK) return status;
Result retval = Result::NOT_INITIALIZED;
for (const auto& factory : mDeviceFactories) {
// 与Hal层通信 factory 为 之前create流程中的IDeviceFactory.hal
Return<void> ret = factory->openDevice(
hidlId,
[&](Result r, const sp<IDevice>& result) {
retval = r;
if (retval == Result::OK) {
*device = new DeviceHalHidl(result);
}
});
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;
}
3.2.2 对Hal层返回的device进行封装返回DeviceHALHidl
// 与Hal层通信 factory 为 之前create流程中的IDeviceFactory.hal
Return<void> ret = factory->openDevice(
hidlId,
[&](Result r, const sp<IDevice>& result) {
retval = r;
if (retval == Result::OK) {
*device = new DeviceHalHidl(result);
}
});
从Hal拿到 IDevice后,当做参数构建DeviceHalHidl
mDevice 通过IDevice初始化
mPrimaryDevice 通过IPrimaryDevice.hal强转 并初始化
class DeviceHalHidl : public DeviceHalInterface, public ConversionHelperHidl
{
sp<IDevice> mDevice;
sp<IPrimaryDevice> mPrimaryDevice; // Null if it's not a primary device.
DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
: ConversionHelperHidl("Device"), mDevice(device),
mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
}
virtual status_t setMasterMute(bool state);
virtual status_t getMasterMute(bool *state);
status_t DeviceHalHidl::setMasterMute(bool state) {
if (mDevice == 0) return NO_INIT;
return processReturn("setMasterMute", mDevice->setMasterMute(state));
}
status_t DeviceHalHidl::getMasterMute(bool *state) {
if (mDevice == 0) return NO_INIT;
Result retval;
Return<void> ret = mDevice->getMasterMute(
[&](Result r, bool mute) {
retval = r;
if (retval == Result::OK) {
*state = mute;
}
});
return processReturn("getMasterMute", ret, retval);
}
所以最后opendevice 最后放入device地址里的是 DeviceHalHidl,mDevice里放的是Hal层的DeviceShim
3.3 hal层 openDevice
3.3.1 hal层 openDevice
IDeviceFactory.hal (4.0)
interface IDevicesFactory {
openDevice(string device) generates (Result retval, IDevice result);
openPrimaryDevice() generates (Result retval, IPrimaryDevice result);
};
DeviceFactory.h
//实现了 IDeviceFactory hal 接口
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
private:
template <class DeviceShim, class Callback>
Return<void> openDevice(const char* moduleName, Callback _hidl_cb);
Return<void> openDevice(const char* moduleName, openDevice_cb _hidl_cb);
static int loadAudioInterface(const char* if_name, audio_hw_device_t** dev);
};
extern "C" IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name);
DevicesFactory openDevice
// /external/swiftshader/src/Common/Version.h
#define MAJOR_VERSION 4
#if MAJOR_VERSION == 2
Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) {
switch (device) {
case IDevicesFactory::Device::PRIMARY:
return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
case IDevicesFactory::Device::A2DP:
return openDevice(AUDIO_HARDWARE_MODULE_ID_A2DP, _hidl_cb);
case IDevicesFactory::Device::USB:
return openDevice(AUDIO_HARDWARE_MODULE_ID_USB, _hidl_cb);
case IDevicesFactory::Device::R_SUBMIX:
return openDevice(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, _hidl_cb);
case IDevicesFactory::Device::STUB:
return openDevice(AUDIO_HARDWARE_MODULE_ID_STUB, _hidl_cb);
}
_hidl_cb(Result::INVALID_ARGUMENTS, nullptr);
return Void();
}
#elif MAJOR_VERSION >= 4
Return<void> DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) {
if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
return openDevice<PrimaryDevice>(moduleName.c_str(), _hidl_cb);
}
return openDevice(moduleName.c_str(), _hidl_cb);
}
//模板 函数
template <class DeviceShim, class Callback>
Return<void> DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
audio_hw_device_t* halDevice;
Result retval(Result::INVALID_ARGUMENTS);
sp<DeviceShim> result;
int halStatus = loadAudioInterface(moduleName, &halDevice);
if (halStatus == OK) {
//返回IDevice
result = new DeviceShim(halDevice);
retval = Result::OK;
} else if (halStatus == -EINVAL) {
retval = Result::NOT_INITIALIZED;
}
_hidl_cb(retval, result);
return Void();
}
3.3.2对返回的硬件device进行封装PrimaryDevice返回
Return<void> ret = factory->openDevice(
hidlId,
[&](Result r, const sp<IDevice>& result) {
retval = r;
if (retval == Result::OK) {
*device = new DeviceHalHidl(result);
}
});
int halStatus = loadAudioInterface(moduleName, &halDevice);
if (halStatus == OK) {
result = new DeviceShim(halDevice);
retval = Result::OK;
} else if (halStatus == -EINVAL) {
retval = Result::NOT_INITIALIZED;
}
/*
lamda表达式 入参为 HidlId 返回值为 Result r和 sp<IDevice>& result
通过_hidl_cb(retval, result); 进行回调返回
*/
DeviceShim封装halDevice(audio_hw_device_t) DeviceShim是模板类 openDevice(moduleName.c_str(), _hidl_cb);
所以实际就是PrimaryDevice
PrimaryDevice的初始化
PrimaryDevice对Device进行封装Device对audio_hw_device_t 进行了封装
PrimaryDevice的setMastMute 就是调用的audio_hw_device_t的setMastMute
struct PrimaryDevice : public IPrimaryDevice {
PrimaryDevice::PrimaryDevice(audio_hw_device_t* device) : mDevice(new Device(device)) {}
Return<Result> PrimaryDevice::initCheck() {
return mDevice->initCheck();
}
Return<Result> PrimaryDevice::setMasterVolume(float volume) {
return mDevice->setMasterVolume(volume);
}
Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
return mDevice->getMasterVolume(_hidl_cb);
}
Return<Result> PrimaryDevice::setMicMute(bool mute) {
return mDevice->setMicMute(mute);
}
Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
return mDevice->getMicMute(_hidl_cb);
}
Return<Result> PrimaryDevice::setMasterMute(bool mute) {
return mDevice->setMasterMute(mute);
}
Device初始化
struct Device : public IDevice, public ParametersUtil {
explicit Device(audio_hw_device_t* device);
// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow.
Return<Result> initCheck() override;
Return<Result> setMasterVolume(float volume) override;
Return<void> getMasterVolume(getMasterVolume_cb _hidl_cb) override;
Return<Result> setMicMute(bool mute) override;
Return<void> getMicMute(getMicMute_cb _hidl_cb) override;
Return<Result> setMasterMute(bool mute) override;
Return<void> getMasterMute(getMasterMute_cb _hidl_cb) override;
Return<void> getInputBufferSize(const AudioConfig& config,
getInputBufferSize_cb _hidl_cb) override;
Return<Result> Device::setMasterMute(bool mute) {
Result retval(Result::NOT_SUPPORTED);
if (mDevice->set_master_mute != NULL) {
retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute));
}
return retval;
}
Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) {
Result retval(Result::NOT_SUPPORTED);
bool mute = false;
if (mDevice->get_master_mute != NULL) {
retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute));
}
_hidl_cb(retval, mute);
return Void();
}
3.3.3 hal loadAudioInterface
// static
int DevicesFactory::loadAudioInterface(const char* if_name, audio_hw_device_t** dev) {
const hw_module_t* mod;
int rc;
//通用的hal模块加载 hw_get_module_by_class 是Hardware.c的公共方法 拿到audio.primary.msm8996的地址
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;
}
// 打开 hw_debice audio_hw_device_open 为Audio.h里的方法
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;
}
return OK;
out:
*dev = NULL;
return rc;
}
3.3.4 audio_hw_device_open 各结构体转换和初始化audio_hw_device到hw_device_t
- audio_hw_device_t 通过TO_HW_DEVICE_T_OPEN 宏定义强转成hw_module_t
- module为 通过hw_get_module_by_class初始化拿到的 hw_module_t 也就是audio_module HAL_MODULE_INFO_SYM
- module->methods 是 hw_module_methods_t 存放module 方法,也就是audio_module HAL_MODULE_INFO_SYM里的.methods = &hal_module_methods
- hw_module_methods_t 里面定义了一个 open方法的引用
- hal_module_methods 里有一个.open = adev_open,
- 所以module->methods->open(module, AUDIO_HARDWARE_INTERFACE, TO_HW_DEVICE_T_OPEN(device)); 就是调用的adev_open方法
typedef struct hw_module_t {
struct hw_module_methods_t* methods;
} hw_module_t;
typedef struct hw_module_methods_t {
/** Open a specific device */
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
} hw_module_methods_t;
#ifdef __cplusplus
#define TO_HW_DEVICE_T_OPEN(x) reinterpret_cast<struct hw_device_t**>(x)
#else
#define TO_HW_DEVICE_T_OPEN(x) (struct hw_device_t**)(x)
#endif
#define AUDIO_HARDWARE_INTERFACE "audio_hw_if"
static inline int audio_hw_device_open(const struct hw_module_t* module,
struct audio_hw_device** device)
{
//TO_HW_DEVICE_T_OPEN是宏定义 将audio_hw_device 转换成hw_device_t
return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,
TO_HW_DEVICE_T_OPEN(device));
}
static inline int audio_hw_device_close(struct audio_hw_device* device)
{
return device->common.close(&device->common);
}
//audio_hw.c
static struct hw_module_methods_t hal_module_methods = {
.open = adev_open,
};
struct audio_module HAL_MODULE_INFO_SYM = {
.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 = "Generic car audio HW HAL",
.author = "The Android Open Source Project",
.methods = &hal_module_methods,
},
};
static int adev_open(const hw_module_t *module,
const char *name, hw_device_t **device) {
static struct generic_audio_device *adev;
adev->device.common.tag = HARDWARE_DEVICE_TAG;
adev->device.common.version = AUDIO_DEVICE_API_VERSION_3_0;
adev->device.common.module = (struct hw_module_t *) module;
adev->device.common.close = adev_close;
adev->device.set_master_mute = adev_set_master_mute;
adev->device.get_master_mute = adev_get_master_mute;
*device = &adev->device.common;
}
struct generic_audio_device {
struct audio_hw_device device; // Constant after init
pthread_mutex_t lock;
unsigned int last_patch_id; // Protected by this->lock
bool master_mute; // Protected by this->lock
bool mic_mute; // Protected by this->lock
struct mixer *mixer; // Protected by this->lock
Hashmap *out_bus_stream_map; // Extended field. Constant after init
};
struct audio_hw_device {
struct hw_device_t common;
int (*set_master_mute)(struct audio_hw_device *dev, bool mute);
int (*get_master_mute)(struct audio_hw_device *dev, bool *mute);
}
typedef struct hw_device_t {
/** tag must be initialized to HARDWARE_DEVICE_TAG */
uint32_t tag;
uint32_t version;
/** reference to the module this device belongs to */
struct hw_module_t* module;
int (*close)(struct hw_device_t* device);
} hw_device_t;
最后为 module->methods->open(module, AUDIO_HARDWARE_INTERFACE,
TO_HW_DEVICE_T_OPEN(device));
完整 audio_hw_device
Audio.h 还定义了一个audio_hw_device,通过openDevice最后的adev_open进行初始化,见3.5
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_voice_volume)(struct audio_hw_device *dev, float volume);
int (*set_master_volume)(struct audio_hw_device *dev, float volume);
int (*get_master_volume)(struct audio_hw_device *dev, float *volume);
int (*set_mode)(struct audio_hw_device *dev, audio_mode_t mode);
int (*set_mic_mute)(struct audio_hw_device *dev, bool state);
int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state);
int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs);
char * (*get_parameters)(const struct audio_hw_device *dev,
const char *keys);
size_t (*get_input_buffer_size)(const struct audio_hw_device *dev,
const struct audio_config *config);
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);
int (*get_microphones)(const struct audio_hw_device *dev,
struct audio_microphone_characteristic_t *mic_array,
size_t *mic_count);
int (*dump)(const struct audio_hw_device *dev, int fd);
int (*set_master_mute)(struct audio_hw_device *dev, bool mute);
int (*get_master_mute)(struct audio_hw_device *dev, bool *mute);
int (*create_audio_patch)(struct audio_hw_device *dev,
unsigned int num_sources,
const struct audio_port_config *sources,
unsigned int num_sinks,
const struct audio_port_config *sinks,
audio_patch_handle_t *handle);
int (*release_audio_patch)(struct audio_hw_device *dev,
audio_patch_handle_t handle);
int (*get_audio_port)(struct audio_hw_device *dev,
struct audio_port *port);
int (*set_audio_port_config)(struct audio_hw_device *dev,
const struct audio_port_config *config);
};
typedef struct audio_hw_device audio_hw_device_t;
3.4 Hardware device_open
3.4.1 hw_get_module_by_class
这是在Hardware.c (f:\q\hardware\libhardware) 7169 2020/2/22
共用方法
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module)
{
int i = 0;
char prop[PATH_MAX] = {0};
char path[PATH_MAX] = {0};
char name[PATH_MAX] = {0};
char prop_name[PATH_MAX] = {0};
// 处理得到path class id转 path
if (inst)
snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
else
strlcpy(name, class_id, PATH_MAX);
/*
* Here we rely on the fact that calling dlopen multiple times on
* the same .so will simply increment a refcount (and not load
* a new copy of the library).
* We also assume that dlopen() is thread-safe.
*/
/* First try a property specific to the class and possibly instance */
snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);
if (property_get(prop_name, prop, NULL) > 0) {
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}
/* Loop through the configuration variants looking for a module */
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}
/* Nothing found, try the default */
if (hw_module_exists(path, sizeof(path), name, "default") == 0) {
goto found;
}
return -ENOENT;
found:
/* load the module, if this fails, we're doomed, and we should not try
* to load a different variant. */
return load(class_id, path, module);
}
3.4.2 load 加载
static int load(const char *id,
const char *path,
const struct hw_module_t **pHmi)
{
int status = -EINVAL;
void *handle = NULL;
struct hw_module_t *hmi = NULL;
#ifdef __ANDROID_VNDK__
const bool try_system = false;
#else
const bool try_system = true;
#endif
/*
* load the symbols resolving undefined symbols before
* dlopen returns. Since RTLD_GLOBAL is not or'd in with
* RTLD_NOW the external symbols will not be global
*/
if (try_system &&
strncmp(path, HAL_LIBRARY_PATH1, strlen(HAL_LIBRARY_PATH1)) == 0) {
/* If the library is in system partition, no need to check
* sphal namespace. Open it with dlopen.
*/
//打开动态链接库
// path = audio.primary=caremu 模拟器
// path = audio.primary.default
// path = audio.primary.msm8996
handle = dlopen(path, RTLD_NOW);
} else {
#if defined(__ANDROID_RECOVERY__)
handle = dlopen(path, RTLD_NOW);
#else
handle = android_load_sphal_library(path, RTLD_NOW);
#endif
}
if (handle == NULL) {
char const *err_str = dlerror();
ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
status = -EINVAL;
goto done;
}
// 根据动态链接库handle 和 符号,返回对应的地址
/* Get the address of the struct hal_module_info. */
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
hmi = (struct hw_module_t *)dlsym(handle, sym);
if (hmi == NULL) {
ALOGE("load: couldn't find symbol %s", sym);
status = -EINVAL;
goto done;
}
/* Check that the id matches */
if (strcmp(id, hmi->id) != 0) {
ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);
status = -EINVAL;
goto done;
}
hmi->dso = handle;
/* success */
status = 0;
done:
if (status != 0) {
hmi = NULL;
if (handle != NULL) {
dlclose(handle);
handle = NULL;
}
} else {
ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
id, path, hmi, handle);
}
// 给 pHmi 复制 Hal层拿到 mod
*pHmi = hmi;
return status;
}
3.4.3 hw_module_t赋值返回
audio_module hw_module_t两个结构体 存的信息一一对应 通过dlsym函数 拿到HAL_MODULE_INFO_SYM 强转成hw_module_t类型 所以hw_module_t 就是 audio_hw.c audio_module HAL_MODULE_INFO_SYM
/**
* Name of the hal_module_info
*/
#define HAL_MODULE_INFO_SYM HMI
/**
* Name of the hal_module_info as a string
*/
#define HAL_MODULE_INFO_SYM_AS_STR "HMI"
static int load(const char *id,
const char *path,
const struct hw_module_t **pHmi)
{
void *handle = NULL;
struct hw_module_t *hmi = NULL;
handle = dlopen(path, RTLD_NOW);
// 根据动态链接库handle 和 符号,返回对应的地址
/* Get the address of the struct hal_module_info. */
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
//dlsym是一个计算机函数,功能是根据动态链接库操作句柄与符号,返回符号对应的地址,不但可以获取函数地址,也可以获取变量地址。
//拿到audio_module HAL_MODULE_INFO_SYM地址 相当于赋值了
hmi = (struct hw_module_t *)dlsym(handle, sym);
// 给 pHmi 复制 Hal层拿到 mod
*pHmi = hmi;
return status;
}
//3.3.3
int DevicesFactory::loadAudioInterface(const char* if_name, audio_hw_device_t** dev) {
rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
// 打开 hw_debice audio_hw_device_open 为Audio.h里的方法
rc = audio_hw_device_open(mod, dev);
}
audio_module hw_module_t两个结构体 存的信息一一对应 通过dlsym函数 拿到HAL_MODULE_INFO_SYM 强转成hw_module_t类型
//Audio_hw.c
struct audio_module {
struct hw_module_t common;
};
struct audio_module HAL_MODULE_INFO_SYM = {
.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 = "Generic car audio HW HAL",
.author = "The Android Open Source Project",
.methods = &hal_module_methods,
},
};
//Hardware.h
typedef struct hw_module_t {
uint32_t tag;
uint16_t module_api_version;
#define version_major module_api_version
uint16_t hal_api_version;
#define version_minor hal_api_version
const char *id;
const char *name;
const char *author;
struct hw_module_methods_t* methods;
void* dso;
#ifdef __LP64__
uint64_t reserved[32-7];
#else
uint32_t reserved[32-7];
#endif
} hw_module_t;
3.5 audio_hw.c adev_open
3.5.1 open方法引用初始化
即module->methods->open(module, AUDIO_HARDWARE_INTERFACE,
TO_HW_DEVICE_T_OPEN(device)); 最终是调用的 audio_hw里的adev_open
static struct hw_module_methods_t hal_module_methods = {
.open = adev_open,
};
3.5.2 各家adev_open实现
vendor是厂商自己定义
//使用原生 模拟器代码说明
struct generic_audio_device {
struct audio_hw_device device; // Constant after init
pthread_mutex_t lock;
unsigned int last_patch_id; // Protected by this->lock
bool master_mute; // Protected by this->lock
bool mic_mute; // Protected by this->lock
struct mixer *mixer; // Protected by this->lock
Hashmap *out_bus_stream_map; // Extended field. Constant after init
};
static int adev_open(const hw_module_t *module,
const char *name, hw_device_t **device) {
static struct generic_audio_device *adev;
if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
return -EINVAL;
pthread_mutex_lock(&adev_init_lock);
if (audio_device_ref_count != 0) {
*device = &adev->device.common;
audio_device_ref_count++;
ALOGV("%s: returning existing instance of adev", __func__);
ALOGV("%s: exit", __func__);
goto unlock;
}
adev = calloc(1, sizeof(struct generic_audio_device));
pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL);
//设置通用引用
adev->device.common.tag = HARDWARE_DEVICE_TAG;
adev->device.common.version = AUDIO_DEVICE_API_VERSION_3_0;
adev->device.common.module = (struct hw_module_t *) module;
adev->device.common.close = adev_close;
//设置方法引用
adev->device.init_check = adev_init_check; // no op
adev->device.set_voice_volume = adev_set_voice_volume; // no op
adev->device.set_master_volume = adev_set_master_volume; // no op
adev->device.get_master_volume = adev_get_master_volume; // no op
// 设置静音
adev->device.set_master_mute = adev_set_master_mute;
adev->device.get_master_mute = adev_get_master_mute;
adev->device.set_mode = adev_set_mode; // no op
adev->device.set_mic_mute = adev_set_mic_mute;
adev->device.get_mic_mute = adev_get_mic_mute;
adev->device.set_parameters = adev_set_parameters; // no op
adev->device.get_parameters = adev_get_parameters; // no op
adev->device.get_input_buffer_size = adev_get_input_buffer_size;
adev->device.open_output_stream = adev_open_output_stream;
adev->device.close_output_stream = adev_close_output_stream;
adev->device.open_input_stream = adev_open_input_stream;
adev->device.close_input_stream = adev_close_input_stream;
adev->device.dump = adev_dump;
// New in AUDIO_DEVICE_API_VERSION_3_0
adev->device.set_audio_port_config = adev_set_audio_port_config;
adev->device.create_audio_patch = adev_create_audio_patch;
adev->device.release_audio_patch = adev_release_audio_patch;
*device = &adev->device.common;
adev->mixer = mixer_open(PCM_CARD);
struct mixer_ctl *ctl;
// Set default mixer ctls
// Enable channels and set volume
for (int i = 0; i < (int)mixer_get_num_ctls(adev->mixer); i++) {
ctl = mixer_get_ctl(adev->mixer, i);
ALOGD("mixer %d name %s", i, mixer_ctl_get_name(ctl));
if (!strcmp(mixer_ctl_get_name(ctl), "Master Playback Volume") ||
!strcmp(mixer_ctl_get_name(ctl), "Capture Volume")) {
for (int z = 0; z < (int)mixer_ctl_get_num_values(ctl); z++) {
ALOGD("set ctl %d to %d", z, 100);
mixer_ctl_set_percent(ctl, z, 100);
}
continue;
}
if (!strcmp(mixer_ctl_get_name(ctl), "Master Playback Switch") ||
!strcmp(mixer_ctl_get_name(ctl), "Capture Switch")) {
for (int z = 0; z < (int)mixer_ctl_get_num_values(ctl); z++) {
ALOGD("set ctl %d to %d", z, 1);
mixer_ctl_set_value(ctl, z, 1);
}
continue;
}
}
// Initialize the bus address to output stream map
adev->out_bus_stream_map = hashmapCreate(5, str_hash_fn, str_eq);
audio_device_ref_count++;
unlock:
pthread_mutex_unlock(&adev_init_lock);
return 0;
}