是否可以动态链接到libcs​​d-client.so以启用Galaxy S4 I9505上的通话录音

时间:2013-06-02 14:54:12

标签: android audio android-ndk alsa

I9505在APQ8064T上运行,与上一代MSM8960相比,HAL层在芯片组上设置通话中语音录制音频路径的方式发生了变化。现在,除了在内核中设置正确的混音器控件之外,它还需要通过libcs​​d-client.so(Qualcomm专有的,近源)库向基带调制解调器发送某种“魔术”命令。

Google通过dlsym libcs​​d-client.so在HAL层为Nexus 4(运行APQ8064)执行此操作(请参阅csd_start_record函数)。但是,在App级别使用带有MediaRecorder.AudioSource.VOICE_DOWNLINK的AudioRecord API将无法正常工作,因为AudioPolicyManagerBase.cpp已被硬编码为仅在通道掩码“AUDIO_CHANNEL_IN_MONO”或“AUDIO_CHANNEL_IN_STEREO”中接收IOProfile,而在通话中录音用例,使用的通道掩码必须是AUDIO_CHANNEL_IN_VOICE_UPLINK或AUDIO_CHANNEL_IN_VOICE_DNLINK。谷歌和三星似乎无意纠正这个问题。这很奇怪,用于记录呼叫的公共android API永远不能保证正常工作。

因此,为了克服这个问题,我决定编写一个NDK可执行文件,以便像谷歌为Nexus 4所做的那样使用csd_start_recording / csd_stop_recording,并使用amix / arec实用程序在root用户设备上进行本机录制。但现在问题来了。

在我的可执行文件中,我调用了csd_client_init和csd_start_record,两个调用都没有返回任何错误,但是logcat在libcs​​d-client.so中显示了一些QMI(Qualcomm MSM Interface)错误,并且记录的wave文件只有静音。有没有人试过类似的东西?我现在完全不知道如何让电话录音工作,而无需将修改过的ROM刷新到设备上。

更新

我再次重复测试,但似乎QMI错误消失了。我猜我上次遇到的QMI错误是因为我在测试期间弄乱了机器的状态。但是,录音仍然无效。结果仍然只是沉默。下面是我用“csd”grep的logcat输出:

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是我的可执行文件。

我的可执行文件执行客户端初始化并在建立调用之后在libcs​​d-client.so上一起调用“csd_start_recording”。从日志中可以看出,“真正的”csd-client通过在设备启动和调节音频设置时注册一些回调来与调制解调器进行双向通信。例如,当呼叫通过时,HAL调用“csd_client_start_voice”。我怀疑我的伪造的csd-client错过了所有那些中间状态,因此没有达到目的。

无论如何,信息在这个阶段真的有限,我感觉就像在黑暗中拍摄。希望有人可以在这里提供帮助。

1 个答案:

答案 0 :(得分:0)

我有解决方案。基本上,您必须调用medisaserver,因为除非您是该语音会话的所有者,否则libcs​​d中的 nothing 将起作用。 avs234.net/temp/csd_calls.c