修改linphone-sdk-android-第四篇
背景
在使用linphone-sdk-android过程中,发现当有一起呼叫在通话中时,又收到一起呼叫,会莫名其妙的播报振铃声音,问题是已经调用linphone-sdk-android提供的接口关闭了振铃声音
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 mCore.setRing(null ); mCore.setRingback(null ); mCore.setRemoteRingbackTone(null ); mCore.setNativeRingingEnabled(false ); mCore.setRingDuringIncomingEarlyMedia(false ); mCore.setVibrationOnIncomingCallEnabled(false ); Reason[] reasons = Reason.values(); for (Reason reason : reasons) { mCore.setCallErrorTone(reason, null ); } ToneID[] toneIds = ToneID.values(); for (ToneID toneId : toneIds) { mCore.setTone(toneId, "" ); }
分析
查看Logcat输出的日志,分析发现有ToneManager
、doStartRingtone
等关键词
1 2 3 4 5 13056-13056/com.guodong.android.linphone I/liblinphone: [ToneManager] [0x934e70ac] state changed : [None, LinphoneCallIncomingReceived] 13056-13056/com.guodong.android.linphone I/liblinphone: [ToneManager] add new session [0x934e70ac] 13056-13056/com.guodong.android.linphone I/liblinphone: [ToneManager] doStopToneToPlaySomethingElse 13056-13056/com.guodong.android.linphone I/liblinphone: [ToneManager] doStartRingtone 13056-13056/com.guodong.android.linphone I/liblinphone: [ToneManager] doStartNamedTone [2]
打开IDE去源码中搜索一番,发现tone-manager.cpp
,在其中找到doStopToneToPlaySomethingElse
、doStartRingtone
、doStartNamedTone
方法,与Logcat日志输出吻合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 void ToneManager::doStopToneToPlaySomethingElse (const std::shared_ptr<CallSession> &session) { lInfo () << "[ToneManager] " << __func__; if (isAnotherSessionInState (session, State::Tone)) { doStopTone (); } } void ToneManager::doStartRingtone (const std::shared_ptr<CallSession> &session) { lInfo () << "[ToneManager] " << __func__; LinphoneCore *lc = getCore ()->getCCore (); if (isAnotherSessionInState (session, State::Call)) { doStartNamedTone (session, LinphoneToneCallWaiting); } else { MSSndCard *ringcard = lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard; if (ringcard && !linphone_core_is_native_ringing_enabled (lc)) { if (!linphone_core_callkit_enabled (lc)){ ms_snd_card_set_stream_type (ringcard, MS_SND_CARD_STREAM_RING); linphone_ringtoneplayer_start (lc->factory, lc->ringtoneplayer, ringcard, lc->sound_conf.local_ring, 2000 ); }else { ms_message ("Callkit is enabled, not playing ringtone." ); } } } } void ToneManager::doStartNamedTone (const std::shared_ptr<CallSession> &session, LinphoneToneID toneId) { lInfo () << "[ToneManager] " << __func__ << " [" << Utils::toString (toneId) << "]" ; LinphoneToneDescription *tone = getToneFromId (toneId); if (tone && tone->audiofile) { playFile (tone->audiofile); } else { MSDtmfGenCustomTone dtmfTone = generateToneFromId (toneId); playTone (session, dtmfTone); } }
好的,现在先找到调用doStopToneToPlaySomethingElse
的方法,在IDE中查找,发现startRingtone
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void ToneManager::printDebugInfo (const std::shared_ptr<CallSession> &session) { auto callState = session->getState (); auto toneState = getState (session); lInfo () << "[ToneManager] [" << session << "] state changed : [" << stateToString (toneState) << ", " << Utils::toString (callState) << "]" ; } void ToneManager::startRingtone (const std::shared_ptr<CallSession> &session) { printDebugInfo (session); setState (session, State::Ringtone); if (!isAnotherSessionInState (session, State::Ringtone) && !isAnotherSessionInState (session, State::Ringback)) { doStopToneToPlaySomethingElse (session); doStartRingtone (session); mStats->number_of_startRingtone++; } }
查看ToneManager::startRingtone
下面的startErrorTone
方法,发现此方法是调用linphone_core_tone_indications_enabled
判断是否可以播报Tone,猜想可以在startRingtone
方法中也增加此判断逻辑
1 2 3 4 5 6 7 8 9 10 void ToneManager::startErrorTone (const std::shared_ptr<CallSession> &session, LinphoneReason reason) { LinphoneCore *lc = getCore ()->getCCore (); if (linphone_core_tone_indications_enabled (lc)) { printDebugInfo (session); doStopToneToPlaySomethingElse (session); doStartErrorTone (session, reason); mStats->number_of_startErrorTone++; } }
不过需要先了解下linphone_core_tone_indications_enabled
方法的实现,此方法位于msic.c
中,方法内部从linphone_config
中读取sound
section下tone_indications
key的值转换为bool_t
类型,大于0为Ture,小于等于0为Flase,其中linphone_config
可以从Java层配置
1 2 3 bool_t linphone_core_tone_indications_enabled (LinphoneCore*lc) { return !!linphone_config_get_int (lc->config,"sound" ,"tone_indications" ,1 ); }
好的,问题分析完毕,可以在startRingtone
方法中也增加此判断逻辑了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void ToneManager::startRingtone (const std::shared_ptr<CallSession> &session) { printDebugInfo (session); setState (session, State::Ringtone); LinphoneCore *lc = getCore ()->getCCore (); if (!linphone_core_tone_indications_enabled (lc)) { return ; } if (!isAnotherSessionInState (session, State::Ringtone) && !isAnotherSessionInState (session, State::Ringback)) { doStopToneToPlaySomethingElse (session); doStartRingtone (session); mStats->number_of_startRingtone++; } }
保存重新编译,等待编译完成拷贝至AS中,现在只需在Java层初始化时配置Config,修改tone_indications
的值即可
1 2 3 mCore.getConfig().setInt("sound" , "tone_indications" , 0 );
happy~