androidstudio打印的信息有如下:
07-12 08:27:17.660 2284-2284/? I/AudioFlinger: loadHwModule() Loaded a2dp audio interface from A2DP Audio HW HAL (audio) handle 7
07-12 08:27:17.660 2284-2284/? I/AudioFlinger: loadHwModule() Loaded usb audio interface from USB audio HW HAL (audio) handle 8
07-12 08:27:17.660 2284-2284/? I/r_submix: adev_open(name=audio_hw_if)
其中的第二行信息就是usb声卡的打印的一条信息。
"frameworks/av/services/audioflinger/AudioFlinger.cpp" 3024 lines --52%--
1573 // loadHwModule_l() must be called with AudioFlinger::mLock held
1574 audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
1575 {
1576 for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1577 if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
1578 ALOGW("loadHwModule() module %s already loaded", name);
1579 return mAudioHwDevs.keyAt(i);
1580 }
1581 }
...
1643 audio_module_handle_t handle = nextUniqueId();
1644 mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
1645
1646 ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",
1647 name, dev->common.module->name, dev->common.module->id, handle);
1648
1649 return handle;
1650
1651 }
这条信息的内容是AudioFlinger打印出来的信息。调用的hardware目录下的工具。
<hardware/libhardware/modules/usbaudio/audio_hal.c>
1074 static struct hw_module_methods_t hal_module_methods = {
1075 .open = adev_open,
1076 };
1077
1078 struct audio_module HAL_MODULE_INFO_SYM = {
1079 .common = {
1080 .tag = HARDWARE_MODULE_TAG,
1081 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1082 .hal_api_version = HARDWARE_HAL_API_VERSION,
1083 .id = AUDIO_HARDWARE_MODULE_ID,
1084 .name = "USB audio HW HAL",
1085 .author = "The Android Open Source Project",
1086 .methods = &hal_module_methods,
1087 },
1088 };
打印的信息都在common这个结构体可以找到出处。
id的定义如下:
libhardware/include/hardware/audio.h:39:#define AUDIO_HARDWARE_MODULE_ID "audio"
libhardware/include/hardware/audio.h:44:#define AUDIO_HARDWARE_INTERFACE "audio_hw_if"
这个open函数如下:
policy文件作用:
gsc@gsc-250:/media/gsc/31269c00-69bd-4eed-814e-bade5758e213/7420_ext/frameworks$ grep -nr "AUDIO_POLICY_CONFIG_FILE"
av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp:2748: if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE,
av/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h:26:#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"
1037 static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device)
1038 {
1039 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1040 return -EINVAL;
1041
1042 struct audio_device *adev = calloc(1, sizeof(struct audio_device));
1043 if (!adev)
1044 return -ENOMEM;
1045
1046 profile_init(&adev->out_profile, PCM_OUT);
1047 profile_init(&adev->in_profile, PCM_IN);
1048
1049 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
1050 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1051 adev->hw_device.common.module = (struct hw_module_t *)module;
1052 adev->hw_device.common.close = adev_close;
1053
1054 adev->hw_device.init_check = adev_init_check;
1055 adev->hw_device.set_voice_volume = adev_set_voice_volume;
1056 adev->hw_device.set_master_volume = adev_set_master_volume;
1057 adev->hw_device.set_mode = adev_set_mode;
1058 adev->hw_device.set_mic_mute = adev_set_mic_mute;
1059 adev->hw_device.get_mic_mute = adev_get_mic_mute;
1060 adev->hw_device.set_parameters = adev_set_parameters;
1061 adev->hw_device.get_parameters = adev_get_parameters;
1062 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
1063 adev->hw_device.open_output_stream = adev_open_output_stream;
1064 adev->hw_device.close_output_stream = adev_close_output_stream;
1065 adev->hw_device.open_input_stream = adev_open_input_stream;
1066 adev->hw_device.close_input_stream = adev_close_input_stream;
1067 adev->hw_device.dump = adev_dump;
1068
1069 *device = &adev->hw_device.common;
1070
1071 return 0;
1072 }
该函数提供了其它操作硬件设备的函数。
out_profile定义于<system/media/alsa_utils/include/alsa_device_profile.h>文件。
typedef struct {
int card;
int device;
int direction; /* PCM_OUT or PCM_IN */
enum pcm_format formats[MAX_PROFILE_FORMATS];
unsigned sample_rates[MAX_PROFILE_SAMPLE_RATES];
unsigned channel_counts[MAX_PROFILE_CHANNEL_COUNTS];
bool is_valid;
/* read from the hardware device */
struct pcm_config default_config;
unsigned min_period_size;
unsigned max_period_size;
unsigned min_channel_count;
unsigned max_channel_count;
} alsa_device_profile;
在USB的Audio HAL层比较关键的两个函数是adev_open_output_stream和adev_open_input_stream,它们分别对应输出和输入流打开操作。
472 static int adev_open_output_stream(struct audio_hw_device *dev,
473 audio_io_handle_t handle,
474 audio_devices_t devices,
475 audio_output_flags_t flags,
476 struct audio_config *config,
477 struct audio_stream_out **stream_out,
478 const char *address /*__unused*/)
479 {
480 ALOGV("adev_open_output_stream() handle:0x%X, device:0x%X, flags:0x%X, addr:%s",
481 handle, devices, flags, address);
482
483 struct audio_device *adev = (struct audio_device *)dev;
484
485 struct stream_out *out;
486
487 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
488 if (!out)
489 return -ENOMEM;
490
491 /* setup function pointers */
492 out->stream.common.get_sample_rate = out_get_sample_rate;
493 out->stream.common.set_sample_rate = out_set_sample_rate;
494 out->stream.common.get_buffer_size = out_get_buffer_size;
495 out->stream.common.get_channels = out_get_channels;
496 out->stream.common.get_format = out_get_format;
497 out->stream.common.set_format = out_set_format;
498 out->stream.common.standby = out_standby;
499 out->stream.common.dump = out_dump;
500 out->stream.common.set_parameters = out_set_parameters;
501 out->stream.common.get_parameters = out_get_parameters;
502 out->stream.common.add_audio_effect = out_add_audio_effect;
503 out->stream.common.remove_audio_effect = out_remove_audio_effect;
504 out->stream.get_latency = out_get_latency;
505 out->stream.set_volume = out_set_volume;
506 out->stream.write = out_write;
507 out->stream.get_render_position = out_get_render_position;
508 out->stream.get_presentation_position = out_get_presentation_position;
509 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
510
511 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
512 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
513
514 out->dev = adev;
515 pthread_mutex_lock(&adev->lock);
516 out->profile = &adev->out_profile;
517
518 // build this to hand to the alsa_device_proxy
519 struct pcm_config proxy_config;
520 memset(&proxy_config, 0, sizeof(proxy_config));
521
522 /* Pull out the card/device pair */
523 parse_card_device_params(address, &(out->profile->card), &(out->profile->device));
...
526
527 profile_read_device_info(out->profile);
528
529 pthread_mutex_unlock(&adev->lock);
530
531 int ret = 0;
532
533 /* Rate */
534 if (config->sample_rate == 0) {
535 proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(out->profile);
536 } else if (profile_is_sample_rate_valid(out->profile, config->sample_rate)) {
537 proxy_config.rate = config->sample_rate;
538 } else {
539 proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(out->profile);
540 ret = -EINVAL;
541 }
542
543 /* Format */
544 if (config->format == AUDIO_FORMAT_DEFAULT) {
545 proxy_config.format = profile_get_default_format(out->profile);
546 config->format = audio_format_from_pcm_format(proxy_config.format);
547 } else {
548 enum pcm_format fmt = pcm_format_from_audio_format(config->format);
549 if (profile_is_format_valid(out->profile, fmt)) {
550 proxy_config.format = fmt;
551 } else {
552 proxy_config.format = profile_get_default_format(out->profile);
553 config->format = audio_format_from_pcm_format(proxy_config.format);
554 ret = -EINVAL;
555 }
556 }
557
558 /* Channels */
559 unsigned proposed_channel_count = 0;
560 if (k_force_channels) {
561 proposed_channel_count = k_force_channels;
562 } else if (config->channel_mask == AUDIO_CHANNEL_NONE) {
563 proposed_channel_count = profile_get_default_channel_count(out->profile);
564 }
565 if (proposed_channel_count != 0) {
566 if (proposed_channel_count <= FCC_2) {
567 // use channel position mask for mono and stereo
568 config->channel_mask = audio_channel_out_mask_from_count(proposed_channel_count);
569 } else {
570 // use channel index mask for multichannel
571 config->channel_mask =
572 audio_channel_mask_for_index_assignment_from_count(proposed_channel_count);
573 }
574 out->hal_channel_count = proposed_channel_count;
575 } else {
576 out->hal_channel_count = audio_channel_count_from_out_mask(config->channel_mask);
577 }
578 /* we can expose any channel mask, and emulate internally based on channel count. */
579 out->hal_channel_mask = config->channel_mask;
580
581 /* no validity checks are needed as proxy_prepare() forces channel_count to be valid.
582 * and we emulate any channel count discrepancies in out_write(). */
583 proxy_config.channels = proposed_channel_count;
584
585 proxy_prepare(&out->proxy, out->profile, &proxy_config);
586
587 /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger. */
588 ret = 0;
589
590 out->conversion_buffer = NULL;
591 out->conversion_buffer_size = 0;
592
593 out->standby = true;
594
595 *stream_out = &out->stream;
596
597 return ret;
...
603 }
这个函数的整体流程还是比较好理解的,首先为创建的output stream关联一些函数操作集合,操作集包括了采样率/通道数/声音格式等这些信息。并且out_write会调用ALSA接口pcm_write写pcm数据。pcm_config
<external/tinyalsa/include/asoundlib.h>
88 /* Configuration for a stream */
89 struct pcm_config {
90 unsigned int channels;
91 unsigned int rate;
92 unsigned int period_size;
93 unsigned int period_count;
94 enum pcm_format format;
95
96 /* Values to use for the ALSA start, stop and silence thresholds, and
97 * silence size. Setting any one of these values to 0 will cause the
98 * default tinyalsa values to be used instead.
99 * Tinyalsa defaults are as follows.
100 *
101 * start_threshold : period_count * period_size
102 * stop_threshold : period_count * period_size
103 * silence_threshold : 0
104 * silence_size : 0
105 */
106 unsigned int start_threshold;
107 unsigned int stop_threshold;
108 unsigned int silence_threshold;
109 unsigned int silence_size;
110
111 /* Minimum number of frames available before pcm_mmap_write() will actually
112 * write into the kernel buffer. Only used if the stream is opened in mmap mode
113 * (pcm_open() called with PCM_MMAP flag set). Use 0 for default.
114 */
115 int avail_min;
116 };
如果在初始化出问题,这个函数是需要跟踪。
ndroid 的USB支持已经由谷歌支持的很好了,基本上只需要开启内核的usb,如下图所示:
其所在的路径如下:
make ARCH=arm64 menuconfig
Device Drivers--->
[*] Sound card support--->
[*] Advanced Linux Sound Architecture ---->
[*] USB sound devices------------->
[*] USB Audio/MIDI driver
配置上述的选项后,则在/dev/snd目录会有声卡信息,并且使用tinyplay能够播放wav类型的音乐。接下来就是安卓层的设置了。
如果该系统有外接codec,则对于安卓6.0上层只需要开启USB host即可,但是如果只有usb这么一个声卡,则有些麻烦,因为audio policy会涉及到选择output stream的问题,output stream是有audio_policy.conf文件来指定的,主要来说就是配置文件中的primary和usb这两个声卡的信息填写方法。
usb host的使能方式是:
"device.mk" 587 lines --66%--
391 PRODUCT_COPY_FILES += \
392 frameworks/native/data/etc/android.hardware.usb.host.xml:system/etc/permissions/android.hardware.usb.host.xml \
393 frameworks/native/data/etc/android.hardware.camera.xml:system/etc/permissions/android.hardware.camera.xml \
394 frameworks/native/data/etc/android.hardware.camera.front.xml:system/etc/permissions/android.hardware.camera.front.xml \
395 frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
396 frameworks/native/data/etc/android.hardware.camera.autofocus.xml:system/etc/permissions/android.hardware.camera.autofocus.xml \
392行添加usb host权限文件即可,该文件实际上只有一行。device.mk是对应android根目录的device下具体型号设备的device.mk文件。
接着将该文件push到系统中reboot即可生效:
adb push frameworks/native/data/etc/android.hardware.usb.host.xml /system/etc/permissions/
USB的audio设备有两种类型一种是usb device一种是usb accessory,这两种设备的区别在于7420侧的usb所扮演的角色不同。如果7420做host,则其要和一个能做slave的设备连接,则在conf文件中,这样的设备被称为usb device,反之被称为usb accessory。其源码中的定义和说明位置如下:
604 /* USB accessory mode: your Android device is a USB device and the dock is a USB host */
605 AUDIO_DEVICE_OUT_USB_ACCESSORY = 0x2000,
606 /* USB host mode: your Android device is a USB host and the dock is a USB device */
607 AUDIO_DEVICE_OUT_USB_DEVICE = 0x4000,
608 AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 0x8000,
609 /* Telephony voice TX path */
610 AUDIO_DEVICE_OUT_TELEPHONY_TX = 0x10000,
"system/media/audio/include/system/audio.h" 1446 lines --38%--
所以在audio_policy.conf文件根据需要配置usb声卡信息;
usb {
outputs {
#usb_accessory {
# sampling_rates 48000
# channel_masks AUDIO_CHANNEL_OUT_STEREO
# formats AUDIO_FORMAT_PCM_16_BIT
# devices AUDIO_DEVICE_OUT_USB_ACCESSORY
#}
usb_device {
sampling_rates 48000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_OUT_USB_DEVICE
}
}
}
在audio_policy.conf文件中还有global_configuration字段,该字段的可以按如下方式填写:
global_configuration {
#attached_output_devices AUDIO_DEVICE_OUT_USB_ACCESSORY
#default_output_device AUDIO_DEVICE_OUT_USB_ACCESSORY
attached_output_devices AUDIO_DEVICE_OUT_USB_DEVICE
default_output_device AUDIO_DEVICE_OUT_USB_DEVICE
#attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC
}
在调试过程中发现了如下错误:
01-01 16:16:14.220 V/AudioPolicyService( 3954): inserting command: 3 at index 0, num commands 0
01-01 16:16:14.220 V/AudioPolicyService( 3954): AudioCommandThread() processing set parameters string card=0;connect=16384;device=0, io 0
01-01 16:16:14.220 V/AudioFlinger( 3954): setParameters(): io 0, keyvalue card=0;connect=16384;device=0, calling pid 3954
01-01 16:16:14.220 V/AudioPolicyService( 3954): AudioCommandThread() going to sleep
01-01 16:16:14.220 V/APM::AudioPolicyManager( 3954): checkOutputForStrategy() strategy 1, moving from output 4 to output 6
01-01 16:16:14.220 V/AudioFlinger( 3954): invalidateStream() stream 0
01-01 16:16:14.220 V/AudioFlinger( 3954): invalidateStream() stream 6
01-01 16:16:14.220 F/APM::AudioPolicyManager( 3954): const TYPE& android::SortedVector<TYPE>::operator[](size_t) const [with TYPE = int; size_t = unsigned int]: index=0 out of range (0)
01-01 16:16:14.220 F/libc ( 3954): Fatal signal 6 (SIGABRT), code -6 in tid 3954 (mediaserver)
01-01 16:16:14.320 F/DEBUG ( 2287): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-01 16:16:14.330 W/NativeCrashListener( 2595): Couldn't find ProcessRecord for pid 3954
01-01 16:16:14.320 F/DEBUG ( 2287): Build fingerprint: 'Android/full_phoenix/phoenix:6.0.1/MMB29T/gsc06080916:eng/dev-keys'
01-01 16:16:14.320 F/DEBUG ( 2287): Revision: '0'
01-01 16:16:14.320 F/DEBUG ( 2287): ABI: 'arm'
01-01 16:16:14.320 F/DEBUG ( 2287): pid: 3954, tid: 3954, name: mediaserver >>> /system/bin/mediaserver <<<
01-01 16:16:14.320 F/DEBUG ( 2287): signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
01-01 16:16:14.330 F/DEBUG ( 2287): Abort message: 'const TYPE& android::SortedVector<TYPE>::operator[](size_t) const [with TYPE = int; size_t = unsigned int]: index=0 out of range (0)'
01-01 16:16:14.340 E/DEBUG ( 2287): AM write failed: Broken pipe
01-01 16:16:14.340 F/DEBUG ( 2287): r0 00000000 r1 00000f72 r2 00000006 r3 f72f6b94
01-01 16:16:14.340 F/DEBUG ( 2287): r4 f72f6b9c r5 f72f6b4c r6 00000000 r7 0000010c
01-01 16:16:14.340 F/DEBUG ( 2287): r8 00000000 r9 f63f8014 sl ffbfbea4 fp f63ce750
01-01 16:16:14.350 F/DEBUG ( 2287): ip 00000006 sp ffbfb9f0 lr f6dc528d pc f6dc767c cpsr 400f0010
01-01 16:16:14.360 F/DEBUG ( 2287):
01-01 16:16:14.360 F/DEBUG ( 2287): backtrace:
01-01 16:16:14.370 F/DEBUG ( 2287): #00 pc 0004267c /system/lib/libc.so (tgkill+12)
01-01 16:16:14.370 F/DEBUG ( 2287): #01 pc 00040289 /system/lib/libc.so (pthread_kill+32)
01-01 16:16:14.370 F/DEBUG ( 2287): #02 pc 0001c9d3 /system/lib/libc.so (raise+10)
01-01 16:16:14.370 F/DEBUG ( 2287): #03 pc 00019c51 /system/lib/libc.so (__libc_android_abort+34)
01-01 16:16:14.370 F/DEBUG ( 2287): #04 pc 000174ac /system/lib/libc.so (abort+4)
01-01 16:16:14.380 F/DEBUG ( 2287): #05 pc 00008173 /system/lib/libcutils.so (__android_log_assert+86)
01-01 16:16:14.380 F/DEBUG ( 2287): #06 pc 00014d75 /system/lib/libaudiopolicymanagerdefault.so
01-01 16:16:14.380 F/DEBUG ( 2287): #07 pc 0001bb95 /system/lib/libaudiopolicymanagerdefault.so (android::AudioPolicyManager::checkOutputForStrategy(android::routing_strategy)+268)
01-01 16:16:14.380 F/DEBUG ( 2287): #08 pc 0001bd81 /system/lib/libaudiopolicymanagerdefault.so (android::AudioPolicyManager::checkOutputForAllStrategies()+56)
01-01 16:16:14.380 F/DEBUG ( 2287): #09 pc 0001c3c5 /system/lib/libaudiopolicymanagerdefault.so (android::AudioPolicyManager::setDeviceConnectionStateInt(unsigned int, audio_policy_dev_state_t, char const*, char const*)+1548)
01-01 16:16:14.380 F/DEBUG ( 2287): #10 pc 000097df /system/lib/libaudiopolicyservice.so
01-01 16:16:14.380 F/DEBUG ( 2287): #11 pc 0008a981 /system/lib/libmedia.so (android::BnAudioPolicyService::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+1164)
01-01 16:16:14.380 F/DEBUG ( 2287): #12 pc 00019999 /system/lib/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+60)
01-01 16:16:14.380 F/DEBUG ( 2287): #13 pc 0001ecf9 /system/lib/libbinder.so (android::IPCThreadState::executeCommand(int)+560)
01-01 16:16:14.390 F/DEBUG ( 2287): #14 pc 0001ee51 /system/lib/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+64)
01-01 16:16:14.390 F/DEBUG ( 2287): #15 pc 0001eeb5 /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+48)
01-01 16:16:14.390 F/DEBUG ( 2287): #16 pc 00001bbb /system/bin/mediaserver
01-01 16:16:14.390 F/DEBUG ( 2287): #17 pc 00017359 /system/lib/libc.so (__libc_init+44)
01-01 16:16:14.390 F/DEBUG ( 2287): #18 pc 00001e0c /system/bin/mediaserver
01-01 16:16:14.520 E/SurfaceFlinger( 2146): ro.sf.lcd_density must be defined as a build property
这时定位问题就变的比较重要了。
gsc@gsc-250:/media/gsc/31269c00-69bd-4eed-814e-bade5758e213/7420_ext$ prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-addr2line -f -e out/target/product/phoenix/symbols/system/lib/libaudiopolicymanagerdefault.so 0001bb95
_ZN7android18AudioPolicyManager22checkOutputForStrategyENS_16routing_strategyE
/media/gsc/31269c00-69bd-4eed-814e-bade5758e213/7420_ext/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp:3835 (discriminator 1)
临时动态推库调试:
1906 . build/envsetup.sh
1907 lunch
1908 mmm frameworks/av/services/audiopolicy/
1909 adb remount
1910 adb push out/target/product/phoenix/system/lib/libaudiopolicymanagerdefault.so /system/lib/
1911 adb push out/target/product/phoenix/system/lib64/libaudiopolicymanagerdefault.so /system/lib64/
1912 adb push out/target/product/phoenix/system/lib64/libaudiopolicyservice.so /system/lib64/
1913 adb push out/target/product/phoenix/system/lib/libaudiopolicyservice.so /system/lib/
1926 mmm frameworks/av/services/audiopolicy/
1927 adb remount
1928 adb push out/target/product/phoenix/system/lib64/libaudiopolicyenginedefault.so /system/lib64/
1929 adb push out/target/product/phoenix/system/lib/libaudiopolicyenginedefault.so /system/lib/
1954 mmm frameworks/av/services/audiopolicy/enginedefault/
1955 adb push audio_policy.conf /system/etc/
1956 adb push out/target/product/phoenix/system/lib64/libaudiopolicyenginedefault.so /system/lib64/
1957 adb push out/target/product/phoenix/system/lib/libaudiopolicyenginedefault.so /system/lib/
1960 mmm hardware/libhardware/modules/usbaudio/
1961 mmm frameworks/av/services/audiopolicy/
1962 adb remount
1963 adb push out/target/product/phoenix/system/lib/hw/audio.usb.default.so /system/lib/
1964 adb push out/target/product/phoenix/system/lib64/hw/audio.usb.default.so /system/lib64/hw/
1965 adb push out/target/product/phoenix/system/lib/hw/audio.usb.default.so /system/lib/hw/
1966 adb push out/target/product/phoenix/system/lib/libaudiopolicymanagerdefault.so /system/lib/
1967 adb push out/target/product/phoenix/system/lib64/libaudiopolicymanagerdefault.so /system/lib64/
1968 adb reboot
1969 mmm hardware/libhardware/modules/usbaudio/
1970 adb remount
1971 adb push out/target/product/phoenix/system/lib/hw/audio.usb.default.so /system/lib/hw/
1972 adb push out/target/product/phoenix/system/lib64/hw/audio.usb.default.so /system/lib64/hw/
1973 adb reboot
一点有用的代码分析
class AudioPolicyManager:<frameworks/av/services/audiopolicy/manager/default/AudioPolicyManager.h>
class AudioPolicyInterface: <frameworks/av/services/audiopolicy/AudioPolicyInterface.h>
class AudioPolicyManagerObserver
AudioPolicyService创建:
<frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp>
在所有实际的操作前其会调用void AudioPolicyService::onFirstRef()
该函数调用了hardware层一些函数,也引用了hardware层一些函数,其定义在如下的函数中。
./hardware/libhardware/include/hardware/hardware.h
84行,未定义USE_LEGACY_AUDIO_POLICY,执行else语句分支。
114行~115行:
mAudioPolicyClient = new AudioPolicyClient(this);
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
<AudioPolicyService.h>
AudioPolicyInterface *mAudioPolicyManager; AudioPolicyClient *mAudioPolicyClient;
<frameworks/av/services/audiopolicy/AudioPolicyInterface.h>
336~337行如下代码:
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface); extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface);
上述函数的实现位置是
<./frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp>
21 extern "C" AudioPolicyInterface* createAudioPolicyManager( 22 AudioPolicyClientInterface *clientInterface) 23 { 24 return new AudioPolicyManager(clientInterface); 25 }
AudioPolicyManager函数定义在<frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp>
2712 AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
2748行会解析/system/etc/audio_policy.conf配置文件,这是在找不到vendor定义的配置文件后的执行动作。2713 : 2714 #ifdef AUDIO_POLICY_TEST 2715 Thread(false), 2716 #endif //AUDIO_POLICY_TEST 2717 mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), 2718 mA2dpSuspended(false), 2719 mSpeakerDrcEnabled(false), 2720 mAudioPortGeneration(1), 2721 mBeaconMuteRefCount(0), 2722 mBeaconPlayingRefCount(0), 2723 mBeaconMuted(false), 2724 mTtsOutputAvailable(false) 2725 { 2726 audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance(); 2727 if (!engineInstance) { 2728 ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__); 2729 return; 2730 } 2731 // Retrieve the Policy Manager Interface 2732 mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>(); 2733 if (mEngine == NULL) { 2734 ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__); 2735 return; 2736 } 2737 mEngine->setObserver(this); 2738 status_t status = mEngine->initCheck(); 2739 ALOG_ASSERT(status == NO_ERROR, "Policy engine not initialized(err=%d)", status); 2740 2741 mUidCached = getuid(); 2742 mpClientInterface = clientInterface; 2743 2744 mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER); 2745 if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, 2746 mHwModules, mAvailableInputDevices, mAvailableOutputDevices, 2747 mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) { 2748 if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE, 2749 mHwModules, mAvailableInputDevices, mAvailableOutputDevices, 2750 mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) { 2751 ALOGE("could not load audio policy configuration file, setting defaults"); 2752 defaultAudioPolicyConfig(); 2753 } 2754 } 2755 // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices 2756 2757 // must be done after reading the policy (since conditionned by Speaker Drc Enabling) 2758 mEngine->initializeVolumeCurves(mSpeakerDrcEnabled); 2759 2760 // open all output streams needed to access attached devices 2761 audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types(); 2762 audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; 2763 for (size_t i = 0; i < mHwModules.size(); i++) { 2764 mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 2765 if (mHwModules[i]->mHandle == 0) { 2766 ALOGW("could not open HW module %s", mHwModules[i]->mName); 2767 continue; 2768 } 2769 // open all output streams needed to access attached devices 2770 // except for direct output streams that are only opened when they are actually 2771 // required by an app. 2772 // This also validates mAvailableOutputDevices list 2773 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 2774 { 2775 const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j]; 。。。 2813 status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(), 2814 &output, 2815 &config, 2816 &outputDesc->mDevice, 2817 String8(""), 2818 &outputDesc->mLatency, 2819 outputDesc->mFlags); 2820 2821 if (status != NO_ERROR) { 2822 ALOGW("Cannot open output stream for device %08x on hw module %s", 2823 outputDesc->mDevice, 2824 mHwModules[i]->mName); 2825 } else { 2826 outputDesc->mSamplingRate = config.sample_rate; 2827 outputDesc->mChannelMask = config.channel_mask; 2828 outputDesc->mFormat = config.format; 2829 2830 for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { 2831 audio_devices_t type = outProfile->mSupportedDevices[k]->type(); 2832 ssize_t index = 2833 mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]); 2834 // give a valid ID to an attached device once confirmed it is reachable 2835 if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) { 2836 mAvailableOutputDevices[index]->attach(mHwModules[i]); 2837 } 2838 } 2839 if (mPrimaryOutput == 0 && 2840 outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 2841 mPrimaryOutput = outputDesc; 2842 } 2843 addOutput(output, outputDesc); 2844 setOutputDevice(outputDesc, 2845 outputDesc->mDevice, 2846 true); 2847 } 2848 } 2849 // open input streams needed to access attached devices to validate 2850 // mAvailableInputDevices list 2851 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 2852 { 2853 const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j]; 2854 2855 if (inProfile->mSupportedDevices.isEmpty()) { 2856 ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName); 2857 continue; 2858 } 2859 // chose first device present in mSupportedDevices also part of 2860 // inputDeviceTypes 2861 audio_devices_t profileType = AUDIO_DEVICE_NONE; 2862 for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 2863 profileType = inProfile->mSupportedDevices[k]->type(); 2864 if (profileType & inputDeviceTypes) { 2865 break; 2866 } 2867 } 2868 if ((profileType & inputDeviceTypes) == 0) { 2869 continue; 2870 } 2871 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile); 2872 2873 inputDesc->mInputSource = AUDIO_SOURCE_MIC; 2874 inputDesc->mDevice = profileType; 2875 2876 // find the address 2877 DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType); 2878 // the inputs vector must be of size 1, but we don't want to crash here 2879 String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress 2880 : String8(""); 2881 ALOGV(" for input device 0x%x using address %s", profileType, address.string()); 2882 ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!"); 2883 2884 audio_config_t config = AUDIO_CONFIG_INITIALIZER; 2885 config.sample_rate = inputDesc->mSamplingRate; 2886 config.channel_mask = inputDesc->mChannelMask; 2887 config.format = inputDesc->mFormat; 2888 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; 2889 status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(), 2890 &input, 2891 &config, 2892 &inputDesc->mDevice, 2893 address, 2894 AUDIO_SOURCE_MIC, 2895 AUDIO_INPUT_FLAG_NONE); 2896 2897 if (status == NO_ERROR) { 2898 for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 2899 audio_devices_t type = inProfile->mSupportedDevices[k]->type(); 2900 ssize_t index = 2901 mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]); 2902 // give a valid ID to an attached device once confirmed it is reachable 2903 if (index >= 0) { 2904 sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index]; 2905 if (!devDesc->isAttached()) { 2906 devDesc->attach(mHwModules[i]); 2907 devDesc->importAudioPort(inProfile); 2908 } 2909 } 2910 } 2911 mpClientInterface->closeInput(input); 2912 } else { 2913 ALOGW("Cannot open input stream for device %08x on hw module %s", 2914 inputDesc->mDevice, 2915 mHwModules[i]->mName); 2916 } 2917 } 2918 } 2919 // make sure all attached devices have been allocated a unique ID 2920 for (size_t i = 0; i < mAvailableOutputDevices.size();) { 2921 if (!mAvailableOutputDevices[i]->isAttached()) { 2922 ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->type()); 2923 mAvailableOutputDevices.remove(mAvailableOutputDevices[i]); 2924 continue; 2925 } 2926 // The device is now validated and can be appended to the available devices of the engine 2927 mEngine->setDeviceConnectionState(mAvailableOutputDevices[i], 2928 AUDIO_POLICY_DEVICE_STATE_AVAILABLE); 2929 i++; 2930 } 2931 for (size_t i = 0; i < mAvailableInputDevices.size();) { 2932 if (!mAvailableInputDevices[i]->isAttached()) { 2933 ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type()); 2934 mAvailableInputDevices.remove(mAvailableInputDevices[i]); 2935 continue; 2936 } 2937 // The device is now validated and can be appended to the available devices of the engine 2938 mEngine->setDeviceConnectionState(mAvailableInputDevices[i], 2939 AUDIO_POLICY_DEVICE_STATE_AVAILABLE); 2940 i++; 2941 } 2942 // make sure default device is reachable 2943 if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) { 2944 ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type()); 2945 } 2946 2947 ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 2948 2949 updateDevicesAndOutputs(); 2950 2951 #ifdef AUDIO_POLICY_TEST 2952 if (mPrimaryOutput != 0) { 2953 AudioParameter outputCmd = AudioParameter(); 2954 outputCmd.addInt(String8("set_id"), 0); 2955 mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, outputCmd.toString()); 2956 2957 mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; 2958 mTestSamplingRate = 44100; 2959 mTestFormat = AUDIO_FORMAT_PCM_16_BIT; 2960 mTestChannels = AUDIO_CHANNEL_OUT_STEREO; 2961 mTestLatencyMs = 0; 2962 mCurOutput = 0; 2963 mDirectOutput = false; 2964 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) { 2965 mTestOutputs[i] = 0; 2966 } 2967 2968 const size_t SIZE = 256; 2969 char buffer[SIZE]; 2970 snprintf(buffer, SIZE, "AudioPolicyManagerTest"); 2971 run(buffer, ANDROID_PRIORITY_AUDIO); 2972 } 2973 #endif //AUDIO_POLICY_TEST 2974 }
经过这个解析后,mAvailableOutputDevices和mAvailableInputDevices包括了所有的输出和输入设备。
2763行针对每一个设备进行加载。
2764行加载Hwmodule。
<frameworks/av/services/audioplolicy/AudioPolicyInterface.h>
class AudioPolicyClientInterface { ... // loads a HW module. virtual audio_module_handle_t loadHwModule(const char *name) = 0; ... }
<./frameworks/av/services/audioflinger/AudioFlinger.cpp>
1561 audio_module_handle_t AudioFlinger::loadHwModule(const char *name) 1562 { 1563 if (name == NULL) { 1564 return 0; 1565 } 1566 if (!settingsAllowed()) { 1567 return 0; 1568 } 1569 Mutex::Autolock _l(mLock); 1570 return loadHwModule_l(name); 1571 } 1572 1573 // loadHwModule_l() must be called with AudioFlinger::mLock held 1574 audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name) 1575 { ... 1583 audio_hw_device_t *dev; 1584 1585 int rc = load_audio_interface(name, &dev); 1643 audio_module_handle_t handle = nextUniqueId(); 1644 mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags)); 1649 return handle; }
load_audio_interface也定义在AudioFlinger函数里的定义如下:
140 static int load_audio_interface(const char *if_name, audio_hw_device_t **dev) 141 { 142 const hw_module_t *mod; 143 int rc; 144 145 rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod); 151 rc = audio_hw_device_open(mod, dev); 167 }
145行查看这类型的hw module是否存在,如果存在则会调用151行的open函数打开设备。
<./hardware/libhardware/include/hardware/audio.h>
680 static inline int audio_hw_device_open(const struct hw_module_t* module,
681 struct audio_hw_device** device) 682 { 683 return module->methods->open(module, AUDIO_HARDWARE_INTERFACE, 684 (struct hw_device_t**)device); 685 }
实际上的open函数定义于具体声卡类型的文件中,针对与usb audio设备,其定义于
<hardware/libhardware/modules/usbaudio/audio_hal.c>
1076 static struct hw_module_methods_t hal_module_methods = { 1077 .open = adev_open, 1078 }; 1079 1080 struct audio_module HAL_MODULE_INFO_SYM = { 1081 .common = { 1082 .tag = HARDWARE_MODULE_TAG, 1083 .module_api_version = AUDIO_MODULE_API_VERSION_0_1, 1084 .hal_api_version = HARDWARE_HAL_API_VERSION, 1085 .id = AUDIO_HARDWARE_MODULE_ID, 1086 .name = "USB audio HW HAL", 1087 .author = "The Android Open Source Project", 1088 .methods = &hal_module_methods, 1089 }, 1090 };
不出意外,这个open应该是成功的。接着打开流程loadHwModule的1644行。创建了一个硬件设备。该类的构造函数如下:
AudioHwDevice(audio_module_handle_t handle,
const char *moduleName,
audio_hw_device_t *hwDevice,
Flags flags)
: mHandle(handle)
, mModuleName(strdup(moduleName))
, mHwDevice(hwDevice)
, mFlags(flags) { }
设备打开和添加的操作是完成了,接下来是打开对应的stream。AudioPolicyManager的2773行。
<./frameworks/av/services/audioflinger/AudioFlinger.cpp>
关键函数是1816行,打开stream。1775 sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_t module, 1776 audio_io_handle_t *output, 1777 audio_config_t *config, 1778 audio_devices_t devices, 1779 const String8& address, 1780 audio_output_flags_t flags) 1781 { 1782 AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices); 1787 audio_hw_device_t *hwDevHal = outHwDev->hwDevice(); 1816 status_t status = outHwDev->openOutputStream( 1817 &outputStream, 1818 *output, 1819 devices, 1820 flags, 1821 config, 1822 address.string()); ... } 1848 status_t AudioFlinger::openOutput(audio_module_handle_t module, 1849 audio_io_handle_t *output, 1850 audio_config_t *config, 1851 audio_devices_t *devices, 1852 const String8& address, 1853 uint32_t *latencyMs, 1854 audio_output_flags_t flags) 1855 { 1870 sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags);
<./frameworks/av/services/audioflinger/AudioHwDevice.cpp>
34 status_t AudioHwDevice::openOutputStream(
AudioStreamOut类的作用是管理对HAL层output Stream的操作。35 AudioStreamOut **ppStreamOut, 36 audio_io_handle_t handle, 37 audio_devices_t devices, 38 audio_output_flags_t flags, 39 struct audio_config *config, 40 const char *address) 41 { 44 AudioStreamOut *outputStream = new AudioStreamOut(this, flags); status_t status = outputStream->open(handle, devices, config, address);
<./frameworks/av/services/audioflinger/AudioStreamOut.cpp>
112 status_t AudioStreamOut::open( 113 audio_io_handle_t handle, 114 audio_devices_t devices, 115 struct audio_config *config, 116 const char *address) 117 { 118 audio_stream_out_t *outStream; 119 int status = hwDev()->open_output_stream( 120 hwDev(), 121 handle, 122 devices, 123 flags, 124 config, 125 &outStream, 126 address); 127 ALOGV("AudioStreamOut::open(), HAL open_output_stream returned " 128 " %p, sampleRate %d, Format %#x, " 129 "channelMask %#x, status %d", 130 outStream, 131 config->sample_rate, 132 config->format, 133 config->channel_mask, 134 status); 135 136 if (status == NO_ERROR) { 137 stream = outStream; 138 mHalFormatIsLinearPcm = audio_is_linear_pcm(config->format); 139 ALOGI("AudioStreamOut::open(), mHalFormatIsLinearPcm = %d", (int)mHalFormatIsLinearPcm); 140 mHalFrameSize = audio_stream_out_frame_size(stream); 141 } 142 143 return status; 144 }
AudioStreamOut.cpp文件里的绝大多数函数是调用HAL层代码完成其工作的。
上面的函数119行调用hardware/libhardware/modules/usbaudio/audio_hal.c的adev_open_output_stream完成实际的打开动作。