Android系统中,对音频设备进行管理的,主要为Audio Flinger与Audio Policy Service。从职能分布上来讲,AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备、某种Stream类型的音频对应什么设备等等。而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如何维护现有系统中的音频设备,以及多个音频流的混音如何处理等等都得由它来完成。
上述两样东西,就不讲了,我也没看,对于蓝牙A2DP需要知道的是,Audio Flinger是如何加载A2DP模块了。
首先看一下,蓝牙A2DP模块的定义:
1461 __attribute__ ((visibility ("default")))
1462 struct audio_module HAL_MODULE_INFO_SYM = {
1463 .common = {
1464 .tag = HARDWARE_MODULE_TAG,
1465 .version_major = 1,
1466 .version_minor = 0,
1467 .id = AUDIO_HARDWARE_MODULE_ID,
1468 .name = "A2DP Audio HW HAL",
1469 .author = "The Android Open Source Project",
1470 .methods = &hal_module_methods,
1471 },
1472 };
从上面这个定义可以看出,关键字为“id”和“name”,对音频设备进行定义。
Audio Flinger(frameworks/av/services/audioflinger/AudioFlinger.cpp)在某个时刻以及某个场景下就需要加载这个HAL模块。
281 static const char * const audio_interfaces[] = {
282 AUDIO_HARDWARE_MODULE_ID_PRIMARY, //"primary"
283 AUDIO_HARDWARE_MODULE_ID_A2DP, //"a2dp"
284 AUDIO_HARDWARE_MODULE_ID_USB, //"usb"
285 };
295 ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
296 for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
297 loadHwModule_l(audio_interfaces[i]);
298 }
调用loadHwMoudle_l不止这一个地方,也不止这三种设备,可能还存在其他的,一般通用支持的就三种,自身设备,蓝牙,usb音频。
1612 // loadHwModule_l() must be called with AudioFlinger::mLock held
1613 audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
1614 {
1615 for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1616 if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
1617 ALOGW("loadHwModule() module %s already loaded", name);
1618 return mAudioHwDevs.keyAt(i);
1619 }
1620 }
1621
1622 audio_hw_device_t *dev;
1623
1624 int rc = load_audio_interface(name, &dev);
...
}
141 static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
142 {
143 const hw_module_t *mod;
144 int rc;
145
146 rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
147 ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,
148 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
149 if (rc) {
150 goto out;
151 }
152 rc = audio_hw_device_open(mod, dev);
153 ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__,
154 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
155 if (rc) {
156 goto out;
157 }
158 if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
159 ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
160 rc = BAD_VALUE;
161 goto out;
162 }
163 return 0;
164
165 out:
166 *dev = NULL;
167 return rc;
168 }
通过hw_get_module_by_class接口,Audio Flinger就能保存多个音频设备了,供audio policy service使用了。后面,再具体看看蓝牙A2DP(audio_hw_device)的实现细节。