最近在做一个音效功能,通过一个app去修改音频设备的一些参数。这时候就需要用到audio_hw.cpp里的adev_set_parameters()来控制。为了更好的实现功能,详细追踪了这个接口的调用和实现流程。
1.AudioManager.setParameters()暴露给上层app的是这个接口,使用方法如下
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setParameters("test");
这个函数的原型是在android/frameworks/base/media/java/android/media/AudioManager.java
/**
* Sets a variable number of parameter values to audio hardware.
*
* @param keyValuePairs list of parameters key value pairs in the form:
* key1=value1;key2=value2;...
*
*/
public void setParameters(String keys) {
AudioSystem.setParameters(keyValuePairs);
}
2. AudioSystem.setParameters()
这里调用了android/frameworks/base/media/java/android/media/AudioSystem.java的native接口
/*
* Sets a group generic audio configuration parameters. The use of these parameters
* are platform dependent, see libaudio
*
* param keyValuePairs list of parameters key value pairs in the form:
* key1=value1;key2=value2;...
*/
public static native int setParameters(String keyValuePairs);
搜索android_media_AudioSystem*,可查到是在android/frameworks/base/core/jni/android_media_AudioSystem.cpp
static jint
android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
{
const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
String8 c_keyValuePairs8;
if (keyValuePairs) {
c_keyValuePairs8 = String8(
reinterpret_cast(c_keyValuePairs),
env->GetStringLength(keyValuePairs));
env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
}
int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8));
return (jint) status;
}
3. AudioSystem::setParameters()
继续追踪,在android/frameworks/av/media/libaudioclient/AudioSystem.cpp
status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
{
const sp& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setParameters(ioHandle, keyValuePairs);
}
4. AudioFlinger->setParameters()
这里通过get_audio_flinger(),调用的是这里android/frameworks/av/services/audioflinger/AudioFlinger.cpp
1220 status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
1221 {
1222 ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d calling uid %d",
1223 ioHandle, keyValuePairs.string(),
1224 IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
1225
1226 // check calling permissions
1227 if (!settingsAllowed()) {
1228 return PERMISSION_DENIED;
1229 }
1230
1231 String8 filteredKeyValuePairs = keyValuePairs;
1232 filterReservedParameters(filteredKeyValuePairs, IPCThreadState::self()->getCallingUid());
1233
1234 ALOGV("%s: filtered keyvalue %s", __func__, filteredKeyValuePairs.string());
1235
1236 // AUDIO_IO_HANDLE_NONE means the parameters are global to the audio hardware interface
1237 if (ioHandle == AUDIO_IO_HANDLE_NONE) {
1238 Mutex::Autolock _l(mLock);
1239 // result will remain NO_INIT if no audio device is present
1240 status_t final_result = NO_INIT;
1241 {
1242 AutoMutex lock(mHardwareLock);
1243 mHardwareStatus = AUDIO_HW_SET_PARAMETER;
1244 for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1245 sp dev = mAudioHwDevs.valueAt(i)->hwDevice();
1246 status_t result = dev->setParameters(filteredKeyValuePairs);
1247 // return success if at least one audio device accepts the parameters as not all
1248 // HALs are requested to support all parameters. If no audio device supports the
1249 // requested parameters, the last error is reported.
1250 if (final_result != NO_ERROR) {
1251 final_result = result;
1252 }
1253 }
1254 mHardwareStatus = AUDIO_HW_IDLE;
1255 }
1256 // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
1257 AudioParameter param = AudioParameter(filteredKeyValuePairs);
1258 String8 value;
1259 if (param.get(String8(AudioParameter::keyBtNrec), value) == NO_ERROR) {
1260 bool btNrecIsOff = (value == AudioParameter::valueOff);
1261 if (mBtNrecIsOff.exchange(btNrecIsOff) != btNrecIsOff) {
1262 for (size_t i = 0; i < mRecordThreads.size(); i++) {
1263 mRecordThreads.valueAt(i)->checkBtNrec();
1264 }
1265 }
1266 }
1267 String8 screenState;
1268 if (param.get(String8(AudioParameter::keyScreenState), screenState) == NO_ERROR) {
1269 bool isOff = (screenState == AudioParameter::valueOff);
1270 if (isOff != (AudioFlinger::mScreenState & 1)) {
1271 AudioFlinger::mScreenState = ((AudioFlinger::mScreenState & ~1) + 2) | isOff;
1272 }
1273 }
1274 return final_result;
1275 }
1276
1277 // hold a strong ref on thread in case closeOutput() or closeInput() is called
1278 // and the thread is exited once the lock is released
1279 sp thread;
1280 {
1281 Mutex::Autolock _l(mLock);
1282 thread = checkPlaybackThread_l(ioHandle);
1283 if (thread == 0) {
1284 thread = checkRecordThread_l(ioHandle);
1285 if (thread == 0) {
1286 thread = checkMmapThread_l(ioHandle);
1287 }
1288 } else if (thread == primaryPlaybackThread_l()) {
1289 // indicate output device change to all input threads for pre processing
1290 AudioParameter param = AudioParameter(filteredKeyValuePairs);
1291 int value;
1292 if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
1293 (value != 0)) {
1294 broacastParametersToRecordThreads_l(filteredKeyValuePairs);
1295 }
1296 }
1297 }
1298 if (thread != 0) {
1299 return thread->setParameters(filteredKeyValuePairs);
1300 }
1301 return BAD_VALUE;
1302 }
在这里,我们会发现用到了智能指针sp
先保留,后面会用上。
5. AudioFlinger继续对AudioFlinger进行分析,先看它的构造函数,里面有个
mDevicesFactoryHal = DevicesFactoryHalInterface::create();
搜索下mDevicesFactoryHal,发现在loadHwModule_l()里有进行openDevice
1795 // loadHwModule_l() must be called with AudioFlinger::mLock held
1796 audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
1797 {
1798 for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1799 if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
1800 ALOGW("loadHwModule() module %s already loaded", name);
1801 return mAudioHwDevs.keyAt(i);
1802 }
1803 }
1804
1805 sp dev;
1806
1807 int rc = mDevicesFactoryHal->openDevice(name, &dev);
1808 if (rc) {
1809 ALOGE("loadHwModule() error %d loading module %s", rc, name);
1810 return AUDIO_MODULE_HANDLE_NONE;
1811 }
1812
1813 mHardwareStatus = AUDIO_HW_INIT;
1814 rc = dev->initCheck();
1815 mHardwareStatus = AUDIO_HW_IDLE;
1816 if (rc) {
1817 ALOGE("loadHwModule() init check error %d for module %s", rc, name);
1818 return AUDIO_MODULE_HANDLE_NONE;
1819 }
1820
1821 // Check and cache this HAL's level of support for master mute and master
1822 // volume. If this is the first HAL opened, and it supports the get
1823 // methods, use the initial values provided by the HAL as the current
1824 // master mute and volume settings.
1825
1826 AudioHwDevice::Flags flags = static_cast(0);
1827 { // scope for auto-lock pattern
1828 AutoMutex lock(mHardwareLock);
1829
1830 if (0 == mAudioHwDevs.size()) {
1831 mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
1832 float mv;
1833 if (OK == dev->getMasterVolume(&mv)) {
1834 mMasterVolume = mv;
1835 }
1836
1837 mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
1838 bool mm;
1839 if (OK == dev->getMasterMute(&mm)) {
1840 mMasterMute = mm;
1841 }
1842 }
1843
1844 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
1845 if (OK == dev->setMasterVolume(mMasterVolume)) {
1846 flags = static_cast(flags |
1847 AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
1848 }
1849
1850 mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
1851 if (OK == dev->setMasterMute(mMasterMute)) {
1852 flags = static_cast(flags |
1853 AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
1854 }
1855
1856 mHardwareStatus = AUDIO_HW_IDLE;
1857 }
1858
1859 audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
1860 mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
1861
1862 ALOGI("loadHwModule() Loaded %s audio interface, handle %d", name, handle);
1863
1864 return handle;
1865
1866 }
可想而知,audio device是通过它进行关联的
6. DevicesFactoryHalInterface继续追踪,android/frameworks/av/media/libaudiohal/DevicesFactoryHalInterface.cpp
sp DevicesFactoryHalInterface::create() {
if (hardware::audio::V4_0::IDevicesFactory::getService() != nullptr) {
return new V4_0::DevicesFactoryHalHybrid();
}
if (hardware::audio::V2_0::IDevicesFactory::getService() != nullptr) {
return new DevicesFactoryHalHybrid();
}
return nullptr;
}
这里会根据不同的HW版本返回不同的实例,android 9.0这里使用的是4.0版本。
7. DevicesFactoryHalHybrid往下看,android/frameworks/av/media/libaudiohal/4.0/DevicesFactoryHalHybrid.cpp
DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
: mLocalFactory(new DevicesFactoryHalLocal()),
mHidlFactory(new DevicesFactoryHalHidl()) {
}
DevicesFactoryHalHybrid::~DevicesFactoryHalHybrid() {
}
status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp *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);
}
这里构造函数有两个对象,openDevice()的时候会根据名字进行二选一。AUDIO_HARDWARE_MODULE_ID_A2DP查询发现是在AudioFlinger里
static const char * const audio_interfaces[] = {
AUDIO_HARDWARE_MODULE_ID_PRIMARY,
AUDIO_HARDWARE_MODULE_ID_A2DP,
AUDIO_HARDWARE_MODULE_ID_USB,
};
看名字推测,A2DP是跟蓝牙相关,USB是U盘,那么PRIMARY就是其他普通情况下使用。
也就是说普通情况下是走的mHidlFactory流程
8. DevicesFactoryHalHidl继续往下看,android/frameworks/av/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
55 status_t DevicesFactoryHalHidl::openDevice(const char *name, sp *device) {
56 if (mDevicesFactory == 0) return NO_INIT;
57 Result retval = Result::NOT_INITIALIZED;
58 Return ret = mDevicesFactory->openDevice(
59 name,
60 [&](Result r, const sp& result) {
61 retval = r;
62 if (retval == Result::OK) {
63 *device = new DeviceHalHidl(result);
64 }
65 });
66 if (ret.isOk()) {
67 if (retval == Result::OK) return OK;
68 else if (retval == Result::INVALID_ARGUMENTS) return BAD_VALUE;
69 else return NO_INIT;
70 }
71 return FAILED_TRANSACTION;
72 }
这里用到了mDevicesFactory,在这个文件里往上搜,发现在构造函数里
mDevicesFactory = IDevicesFactory::getService();
这是个binder接口
9. DevicesFactory.impl.h继续追,在android/hardware/interfaces/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.impl.h发现,这是个public接口
Return DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) {
if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
return openDevice(moduleName.c_str(), _hidl_cb);
}
return openDevice(moduleName.c_str(), _hidl_cb);
}
在本文第7点中我们推测,普通情况下是使用PRIMARY,那么按流程走的是模板类,下面是它的private实现
Return DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) {
return openDevice(moduleName, _hidl_cb);
}
template
Return DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
audio_hw_device_t* halDevice;
Result retval(Result::INVALID_ARGUMENTS);
sp result;
int halStatus = loadAudioInterface(moduleName, &halDevice);
if (halStatus == OK) {
result = new DeviceShim(halDevice);
retval = Result::OK;
} else if (halStatus == -EINVAL) {
retval = Result::NOT_INITIALIZED;
}
_hidl_cb(retval, result);
return Void();
}
主要是调用loadAudioInterface,然后返回PrimaryDevice的对象
80 int DevicesFactory::loadAudioInterface(const char* if_name, audio_hw_device_t** dev) {
81 const hw_module_t* mod;
82 int rc;
83
84 rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
85 if (rc) {
86 ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
87 if_name, strerror(-rc));
88 goto out;
89 }
90 rc = audio_hw_device_open(mod, dev);
91 if (rc) {
92 ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
93 if_name, strerror(-rc));
94 goto out;
95 }
96 if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
97 ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
98 rc = -EINVAL;
99 audio_hw_device_close(*dev);
100 goto out;
101 }
102 return OK;
103
104 out:
105 *dev = NULL;
106 return rc;
107 }
这里就从Hal层获取到了dev,这是个PrimaryDevice的对象
10. PrimaryDevice.impl.h继续往下分析,android/hardware/interfaces/audio/core/all-versions/default/include/core/all-versions/default/PrimaryDevice.impl.h
dev获取到了,那么我们回到第4点dev->setParameters,那么它应该是
Return PrimaryDevice::setParameters(const hidl_vec& context,
const hidl_vec& parameters) {
return mDevice->setParameters(context, parameters);
}
这里的mDevice是什么,我们往上看构造函数
PrimaryDevice::PrimaryDevice(audio_hw_device_t* device) : mDevice(new Device(device)) {}
到这里,还不能停
11. Device.impl.h继续查,android/hardware/interfaces/audio/core/all-versions/default/include/core/all-versions/default/Device.impl.h,这里构造函数没什么特别的
Device::Device(audio_hw_device_t* device) : mDevice(device) {}
我们看它的setParameters
Return Device::setParameters(const hidl_vec& context,
const hidl_vec& parameters) {
return setParametersImpl(context, parameters);
}
12. ParametersUtil.impl.h
继续追踪,android/hardware/interfaces/audio/core/all-versions/default/include/core/all-versions/default/ParametersUtil.impl.h
139 Result ParametersUtil::setParametersImpl(const hidl_vec& context,
140 const hidl_vec& parameters) {
141 AudioParameter params;
142 for (auto& pair : context) {
143 params.add(String8(pair.key.c_str()), String8(pair.value.c_str()));
144 }
145 for (size_t i = 0; i < parameters.size(); ++i) {
146 params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
147 }
148 return setParams(params);
149 }
156 Result ParametersUtil::setParams(const AudioParameter& param) {
157 int halStatus = halSetParameters(param.toString().string());
158 return util::analyzeStatus(halStatus);
159 }
13. Device.impl.h
又回到了这里
59 int Device::halSetParameters(const char* keysAndValues) {
60 return mDevice->set_parameters(mDevice, keysAndValues);
61 }
可以看出,最终调用的是audio_hw_device_t里的set_parameters
14. audio_hw_device在android/hardware/libhardware/include/hardware/audio.h查到这个结构体
typedef struct audio_hw_device audio_hw_device_t;
那么这个结构里成员是在哪里赋值的呢
15. audio_hw在android/vendor/mediatek/proprietary_tv/open/hardware/audio/audio_hw_7_0/audio_hw.cpp这里,adev_open()的时候发现
adev->device.set_parameters = adev_set_parameters;
adev->device.get_parameters = adev_get_parameters;
那么,HAL最终实现的地方就找到了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)