I9505 работает на APQ8064T, и то, как уровень HAL настраивает звуковой путь записи голоса во время разговора на наборе микросхем, изменился по сравнению с MSM8960 предыдущего поколения. Теперь, в дополнение к установке правильных элементов управления микшером в ядре, также требуется отправить какие-то «волшебные» команды через библиотеку libcsd-client.so (собственная библиотека Qualcomm, закрытый исходный код) на модем основной полосы частот.
Google делает это для Nexus 4 (использует APQ8064) на уровне HAL с помощью dlsym libcsd-client.so (см. csd_start_record). Однако использование AudioRecord API с MediaRecorder.AudioSource.VOICE_DOWNLINK на уровне приложения не будет работать, поскольку AudioPolicyManagerBase.cpp был жестко запрограммирован для приема IOProfile только с маской канала "AUDIO_CHANNEL_IN_MONO" или "AUDIO_CHANNEL_IN_STEREO", в то время как в случае использования записи голоса во время разговора используемые маски каналов либо AUDIO_CHANNEL_IN_VOICE_UPLINK, либо AUDIO_CHANNEL_IN_VOICE_DNLINK. Похоже, что ни Google, ни Samsung не собираются исправлять эту проблему. Странно, что общедоступный Android API для записи звонков никогда не гарантируется, что он будет работать должным образом.
Итак, чтобы решить эту проблему, я решил написать исполняемый файл NDK для dlsym csd_start_recording/csd_stop_recording точно так же, как Google сделал для Nexus 4, и использовать утилиту amix/arec для записи на устройстве с root-доступом. Но теперь возникает вопрос.
В моем исполняемом файле я вызвал csd_client_init и csd_start_record, оба вызова не вернули ошибок, но logcat показывает некоторую ошибку QMI (Qualcomm MSM Interface) из libcsd-client.so, и в записанном волновом файле не было ничего, кроме тишины. Кто-нибудь пробовал что-то подобное? Теперь я совершенно не понимаю, как заставить работать запись звонков без необходимости прошивать модифицированное ПЗУ на устройстве.
ОБНОВЛЕНИЕ
Я повторил тест еще раз, но кажется, что ошибки QMI исчезли. Я предполагаю, что ошибки QMI, которые я встретил в прошлый раз, были связаны с тем, что я испортил состояние машины во время теста. Однако запись по-прежнему не работает. В результате пока только тишина. Ниже приведен вывод logcat, который я grep с помощью «csd»:
D/ ( 217): csd_client_disable_device: rx 7, tx 4, client_state=1
E/ ( 217): csd_client_disable_device: Disable received in invalid state:1
D/ ( 217): csd_client_enable_device: APQ rx 7, tx 34, ec 43, tty 0x10012 state 1
D/ ( 217): csd_client_enable_device: Remote rx -1, tx -1
E/ ( 217): csd_client_enable_device: Enable received in invalid state 1
D/ ( 217): csd_client_start_voice: State 1
D/ ( 217): csd_client_async_cb: msg_id 0x33 result 0 error 0
D/ ( 217): csd_client_async_cb: msg_id 0x34 result 0 error 0
D/ ( 217): csd_client_async_cb: msg_id 0x55 result 0 error 0
D/ ( 217): csd_client_async_cb: msg_id 0x5c result 0 error 0
D/ ( 217): csd_client_async_cb: msg_id 0x4c result 0 error 0
D/ ( 217): csd_client_async_cb: msg_id 0x4c result 0 error 0
D/ ( 217): csd_client_async_cb: msg_id 0x57 result 0 error 0
D/ ( 217): csd_client_async_cb: msg_id 0x36 result 0 error 0
D/ ( 217): csd_client_async_cb: msg_id 0x3e result 0 error 0
D/ ( 217): csd_client_async_cb: msg_id 0x36 result 0 error 0
D/ ( 217): csd_client_volume: volume 0, state 2, rc 0
D/ ( 217): csd_client_async_cb: msg_id 0x37 result 0 error 0
D/ ( 217): csd_client_set_rx_mute: mute 0, state 2, rc 0
D/ ( 217): csd_client_async_cb: msg_id 0x3e result 0 error 0
D/ ( 217): csd_client_mic_mute: mute 0, state 2, rc 0
D/ ( 217): csd_client_async_cb: msg_id 0x36 result 0 error 0
D/ ( 217): csd_client_volume: volume 4, state 2, rc 0
D/ ( 6801): csd_client_init
E/ ( 6801): csd_client_service_init: Invalid rx device 0, setting to handset
E/ ( 6801): csd_client_service_init: Invalid tx device 0, setting to handset
D/ ( 217): csd_client_stop_voice: State 2
D/ ( 217): csd_client_async_cb: msg_id 0x58 result 1 error 3
E/ ( 217): csd_client_stop_voice: Error -1 stopping voice manager
E/ALSADevice( 217): s_close: csd_client error -1
PID 217 — это оригинальный csd_client на устройстве, PID 6801 — мой исполняемый файл.
Мой исполняемый файл выполняет инициализацию клиента и вызывает «csd_start_recording» на libcsd-client.so вместе ПОСЛЕ установления вызова. Из журнала видно, что «настоящий» csd-клиент осуществляет двустороннюю связь с модемом, регистрируя некоторые обратные вызовы при загрузке устройства и регулируя настройки звука с этого момента. Например, «csd_client_start_voice» вызывается HAL, когда вызов проходит. Я подозреваю, что мой поддельный csd-клиент пропускает все эти промежуточные состояния, в результате чего цель не удалась.
В любом случае, на данном этапе информация действительно ограничена, и я чувствую, что стреляю в темноте. Надеюсь, кто-то может помочь здесь.
csd_client_service_init: Invalid rx device 0, setting to handset
csd_client_service_init: Invalid tx device 0, setting to handset
не имеет значения, потому что csd-клиент, инициализированный /system/bin/mediaserver, также выдает их при загрузке. - person Simon Weng   schedule 05.06.2013AudioPolicyManagerBase
из CodeAurora. Вместо этого, я думаю, они ссылались на конкретную версию из git Google, предназначенную для реализации Nexus 4. Я могу сказать, что я уверен, потому что, если я используюMediaRecorder.AudioSource.VOICE_DOWNLINK
в AudioRecord,AudioPolicyManagerBase
жаловался на журнал ошибок, в котором говорилось, что не может получить входной профиль ... и он распечатывал маску канала в запросе, который не определен на CodeAurora, но тот, который указан в исходниках Google. - person Simon Weng   schedule 07.06.2013