I9505 は APQ8064T で動作し、HAL レイヤーがチップセットで通話中の音声録音オーディオ パスをセットアップする方法が、前世代の MSM8960 と比較して変更されました。現在、カーネルで正しいミキサー コントロールを設定するだけでなく、libcsd-client.so (Qualcomm 独自のソースに近い) ライブラリを介して何らかの「魔法の」コマンドをベースバンド モデムに送信する必要もあります。
Google は、Nexus 4 (APQ8064 を実行) に対して、libcsd-client.so の dlsym によって HAL レイヤーでこれを行います ( csd_start_record関数を参照)。ただし、AudioRecord API を MediaRecorder.AudioSource.VOICE_DOWNLINK と共にアプリ レベルで使用しても機能しません。AudioPolicyManagerBase.cppは、通話中の音声録音中にチャネル マスク「AUDIO_CHANNEL_IN_MONO」または「AUDIO_CHANNEL_IN_STEREO」のみを使用して IOProfile を取り込むようにハードコーディングされているためです。ユースケースでは、使用中のチャネル マスクは AUDIO_CHANNEL_IN_VOICE_UPLINK または AUDIO_CHANNEL_IN_VOICE_DNLINK のいずれかである必要があります。Google も Samsung も、この問題を修正するつもりはないようです。これは、呼び出しを記録するためのパブリック android API が適切に動作することが保証されていないことは奇妙です。
そこで、この問題を克服するために、Google が Nexus 4 で行ったのと同じ方法で csd_start_recording/csd_stop_recording を dlsym する NDK 実行可能ファイルを作成し、amix/arec ユーティリティを使用してルート化されたデバイスでネイティブに記録を行うことにしました。しかし今、疑問が生じます。
実行可能ファイルで csd_client_init と csd_start_record を呼び出しました。どちらの呼び出しでもエラーは返されませんでしたが、logcat は libcsd-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 は私の実行可能ファイルです。
私の実行可能ファイルはクライアントの初期化を行い、呼び出しが確立された後に libcsd-client.so で「csd_start_recording」を呼び出します。ログから見ると、デバイスの起動時にいくつかのコールバックを登録し、それ以降オーディオ設定を調整することで、「実際の」csd-client がモデムと双方向通信を行っていることが明らかです。たとえば、「csd_client_start_voice」は、通話が成功したときに HAL によって呼び出されます。偽造された csd-client がこれらの中間状態をすべて見逃していると思われ、その結果、目的を達成できませんでした。
とにかく、この段階では情報が本当に限られているので、暗闇で撮影したい気分です. 誰かがここで助けてくれることを願っています。