//处理通话状态变化。其实通话状态变化分成两个部分,一部分处理prestate,可以理解为source(src),一部分处理nextState,可以理解为target(目标状态处理)
define:HandleCallStateUpdated
void AudioControlManager::HandleCallStateUpdated(
HandleNextState(callObjectPtr, nextState);
//来电消息处理
void AudioControlManager::HandleNextState(sptr &callObjectPtr, TelCallState nextState)
case TelCallState::CALL_STATUS_INCOMING:
event = AudioEvent::NEW_INCOMING_CALL;
DelayedSingleton::GetInstance()->ProcessEvent(event);
bool AudioSceneProcessor::ProcessEvent(AudioEvent event)
reportAudioStateChangeQueue.submit(= { ProcessEventInner(event); });
void AudioSceneProcessor::ProcessEventInner(AudioEvent event)
switch (event) {
case AudioEvent::NEW_INCOMING_CALL:
currentState_ = std::make_unique();
currentState_->ProcessEvent(event); //这个地方相当于是一个状态机,不同的状态处理同一个event,处理方式也不同
---------------------------可爱分隔线-------------------------------------
//单路通话 inactive_state处理NEW_INCOMING_CALL
bool InActiveState::ProcessEvent(int32_t event)
case AudioEvent::NEW_INCOMING_CALL:
result = DelayedSingleton::GetInstance()->ProcessEvent(AudioEvent::SWITCH_INCOMING_STATE); //会将状态机切到incoming_state
memberFuncMap_[AudioEvent::SWITCH_INCOMING_STATE] = &AudioSceneProcessor::SwitchIncoming;
bool AudioSceneProcessor::SwitchIncoming()
DelayedSingleton::GetInstance()->StopRingtone();
// play ringtone while incoming state
DelayedSingleton<AudioControlManager>::GetInstance()->PlayRingtone(); //这个地方前边我们已经说明了来电响铃的逻辑,实际就是调用audioPlayer的播放
//多路通话 cs_call_state/ims_call_state/holding_state/incoming_state 上一路通话的状态可能是这几个状态机处理第二路来电消息
//处理上一路通话由incoming到active的时候
void AudioControlManager::HandleNewActiveCall(sptr &callObjectPtr)
case CallType::TYPE_IMS:
event = AudioEvent::NEW_ACTIVE_IMS_CALL;
bool AudioSceneProcessor::ProcessEvent(AudioEvent event)
reportAudioStateChangeQueue.submit(= { ProcessEventInner(event); });
void AudioSceneProcessor::ProcessEventInner(AudioEvent event)
case AudioEvent::NEW_ACTIVE_IMS_CALL:
currentState_->ProcessEvent(event); //currentState_ = IncomingState 来电
bool IncomingState::ProcessEvent(int32_t event)
case AudioEvent::NEW_ACTIVE_IMS_CALL:
result = DelayedSingleton::GetInstance()->ProcessEvent(
AudioEvent::SWITCH_IMS_CALL_STATE);
bool AudioSceneProcessor::ProcessEvent(AudioEvent event)
reportAudioStateChangeQueue.submit(= { ProcessEventInner(event); });
void AudioSceneProcessor::ProcessEventInner(AudioEvent event)
case AudioEvent::SWITCH_IMS_CALL_STATE:
SwitchState(event);
memberFuncMap_[AudioEvent::SWITCH_IMS_CALL_STATE] = &AudioSceneProcessor::SwitchIMS;
bool AudioSceneProcessor::SwitchState(AudioEvent event)
{
auto itFunc = memberFuncMap_.find(event);
if (itFunc != memberFuncMap_.end() && itFunc->second != nullptr) {
auto memberFunc = itFunc->second;
return (this->*memberFunc)();
}
return false;
}
//第一路通话active,状态机置为 IMSCallState。同理CS通话接听成功逻辑类似。通话hold也是一个逻辑,就不一一罗列了
bool AudioSceneProcessor::SwitchIMS()
currentState_ = std::make_unique();
goto:HandleCallStateUpdated
//第二路通话来电的消息处理—直接从消息处理说起
bool IMSCallState::ProcessEvent(int32_t event)
case AudioEvent::NEW_INCOMING_CALL:
result = DelayedSingleton::GetInstance()->PlayWaitingTone();
int32_t AudioControlManager::PlayWaitingTone()
{
return PlayCallTone(ToneDescriptor::TONE_WAITING);
}
int32_t AudioControlManager::PlayCallTone(ToneDescriptor type)
tone_ = std::make_unique(type); //初始化Tone,根据传入的ToneDescription,当前为TONE_WAITING
if (tone_->Play() != TELEPHONY_SUCCESS) {
int32_t Tone::Play()
//判断是否使用TonePlayer进行播放,历史上会铃声,等待声都是通话管理本地进行播放的,非调用音频框架进行播放。
if (IsUseTonePlayer(currentToneDescriptor_)) {
//初始化TonePlayer
if (!InitTonePlayer()) {
tonePlayer_->StartTone();
bool Tone::IsUseTonePlayer(ToneDescriptor tone)
case ToneDescriptor::TONE_RINGBACK:
case ToneDescriptor::TONE_WAITING:
ret = true;
bool Tone::InitTonePlayer()
//根据当前的description获取当前需要加载stream的类型
StreamUsage streamUsage = GetStreamUsageByToneType(currentToneDescriptor_);
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-audio-kit/js-apis-audio.md#streamusage
STREAM_USAGE_VOICE_COMMUNICATION 2 语音通信。
//stream类型为通话类型
case ToneDescriptor::TONE_RINGBACK:
case ToneDescriptor::TONE_WAITING:
streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION;
tonePlayer_ = TonePlayer::Create(rendererInfo);
//铃声类型为call_waiting 等待声
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-audio-kit/js-apis-audio-sys.md#tonetype9
TONE_TYPE_COMMON_SUPERVISORY_CALL_WAITING 106 呼叫监管音调,呼叫等待。
TONE_TYPE_COMMON_SUPERVISORY_RINGTONE 107 呼叫监管音调,铃声。
ToneType toneType = ConvertToneDescriptorToToneType(currentToneDescriptor_);
AudioStandard::ToneType Tone::ConvertToneDescriptorToToneType(ToneDescriptor tone)
AudioStandard::ToneType Tone::ConvertCallToneDescriptorToToneType(ToneDescriptor tone)
case ToneDescriptor::TONE_WAITING:
tonType = ToneType::TONE_TYPE_COMMON_SUPERVISORY_CALL_WAITING;
//tonePlayer 根据Tone的类型去加载相应的资源文件,用于播放
if (!tonePlayer_->LoadTone(toneType)) {
//音频框架正式播放多路通话的waiting声音
tonePlayer_->StartTone();