/* * Copyright (C) 2021-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "audio_control_manager.h" #include "call_ability_report_proxy.h" #include "call_control_manager.h" #include "call_dialog.h" #include "call_state_processor.h" #include "common_type.h" #include "distributed_call_manager.h" #include "telephony_log_wrapper.h" #include "audio_system_manager.h" #include "audio_routing_manager.h" #include "audio_device_info.h" #include "audio_info.h" #include "voip_call_connection.h" #include "settings_datashare_helper.h" namespace OHOS { namespace Telephony { using namespace AudioStandard; constexpr int32_t DTMF_PLAY_TIME = 30; constexpr int32_t VOICE_TYPE = 0; constexpr int32_t CRS_TYPE = 2; constexpr int32_t CALL_ENDED_PLAY_TIME = 300; AudioControlManager::AudioControlManager() : isLocalRingbackNeeded_(false), ring_(nullptr), tone_(nullptr), sound_(nullptr) {} AudioControlManager::~AudioControlManager() { DelayedSingleton::GetInstance()->UnsetDeviceChangeCallback(); DelayedSingleton::GetInstance()->UnsetAudioPreferDeviceChangeCallback(); DelayedSingleton::GetInstance()->UnsetAudioMicStateChangeCallback(); } void AudioControlManager::Init() { DelayedSingleton::GetInstance()->Init(); DelayedSingleton::GetInstance()->Init(); } void AudioControlManager::UpdateForegroundLiveCall() { int32_t callId = DelayedSingleton::GetInstance()->GetAudioForegroundLiveCall(); if (callId == INVALID_CALLID) { frontCall_ = nullptr; DelayedSingleton::GetInstance()->SetMicrophoneMute(false); TELEPHONY_LOGE("callId is invalid"); return; } sptr liveCall = CallObjectManager::GetOneCallObject(callId); if (liveCall == nullptr) { TELEPHONY_LOGE("liveCall is nullptr"); return; } if (liveCall->GetTelCallState() == TelCallState::CALL_STATUS_ACTIVE || liveCall->GetTelCallState() == TelCallState::CALL_STATUS_DIALING || liveCall->GetTelCallState() == TelCallState::CALL_STATUS_ALERTING) { if (frontCall_ == nullptr) { frontCall_ = liveCall; } else { int32_t frontCallId = frontCall_->GetCallID(); int32_t liveCallId = liveCall->GetCallID(); if (frontCallId != liveCallId) { frontCall_ = liveCall; } } bool frontCallMute = frontCall_->IsMuted(); bool currentMute = DelayedSingleton::GetInstance()->IsMicrophoneMute(); if (frontCallMute != currentMute) { SetMute(frontCallMute); } } } void AudioControlManager::HandleCallStateUpdatedForVoip( sptr &callObjectPtr, TelCallState priorState, TelCallState nextState) { TELEPHONY_LOGI("control audio for voip start, callId:%{public}d, priorState:%{public}d, nextState:%{public}d", callObjectPtr->GetCallID(), priorState, nextState); if (priorState == TelCallState::CALL_STATUS_INCOMING && nextState == TelCallState::CALL_STATUS_INCOMING) { if (DelayedSingleton::GetInstance()->GetVoipCallNum() == 1) { AudioDevice device = { .deviceType = AudioDeviceType::DEVICE_EARPIECE, .address = { 0 }, }; if (DelayedSingleton::GetInstance()->GetPreferredOutputAudioDevice(device) == TELEPHONY_SUCCESS) { DelayedSingleton::GetInstance()->SetCurrentAudioDevice(device.deviceType); TELEPHONY_LOGI("control audio for voip finish, callId:%{public}d", callObjectPtr->GetCallID()); } else { TELEPHONY_LOGE("current audio device nullptr when control audio for voip"); } } } } void AudioControlManager::CallStateUpdated( sptr &callObjectPtr, TelCallState priorState, TelCallState nextState) { if (callObjectPtr == nullptr) { TELEPHONY_LOGE("call object nullptr"); return; } if (callObjectPtr->GetCallType() == CallType::TYPE_VOIP) { HandleCallStateUpdatedForVoip(callObjectPtr, priorState, nextState); return; } std::lock_guard lock(mutex_); if (totalCalls_.count(callObjectPtr) == 0) { int32_t callId = callObjectPtr->GetCallID(); TelCallState callState = callObjectPtr->GetTelCallState(); TELEPHONY_LOGI("add new call, callid:%{public}d , callstate:%{public}d", callId, callState); totalCalls_.insert(callObjectPtr); } HandleCallStateUpdated(callObjectPtr, priorState, nextState); if (nextState == TelCallState::CALL_STATUS_DISCONNECTED && totalCalls_.count(callObjectPtr) > 0) { totalCalls_.erase(callObjectPtr); } UpdateForegroundLiveCall(); } void AudioControlManager::VideoStateUpdated( sptr &callObjectPtr, VideoStateType priorVideoState, VideoStateType nextVideoState) { if (callObjectPtr == nullptr) { TELEPHONY_LOGE("call object nullptr"); return; } if (callObjectPtr->GetCallType() != CallType::TYPE_IMS) { TELEPHONY_LOGE("other call not need control audio"); return; } AudioDevice device = { .deviceType = AudioDeviceType::DEVICE_SPEAKER, .address = { 0 }, }; AudioDeviceType initDeviceType = GetInitAudioDeviceType(); if (callObjectPtr->GetCrsType() == CRS_TYPE) { AudioStandard::AudioRingerMode ringMode = DelayedSingleton::GetInstance()->GetRingerMode(); if (ringMode != AudioStandard::AudioRingerMode::RINGER_MODE_NORMAL) { if (initDeviceType == AudioDeviceType::DEVICE_WIRED_HEADSET || initDeviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) { device.deviceType = initDeviceType; } } TELEPHONY_LOGI("crs ring tone should be speaker"); SetAudioDevice(device); return; } CheckTypeAndSetAudioDevice(callObjectPtr, priorVideoState, nextVideoState, initDeviceType, device); } void AudioControlManager::CheckTypeAndSetAudioDevice(sptr &callObjectPtr, VideoStateType priorVideoState, VideoStateType nextVideoState, AudioDeviceType &initDeviceType, AudioDevice &device) { TelCallState telCallState = callObjectPtr->GetTelCallState(); if (!IsVideoCall(priorVideoState) && IsVideoCall(nextVideoState) && (telCallState != TelCallState::CALL_STATUS_INCOMING && telCallState != TelCallState::CALL_STATUS_WAITING)) { if (callObjectPtr->GetOriginalCallType() == VOICE_TYPE && (telCallState == TelCallState::CALL_STATUS_DIALING || telCallState == TelCallState::CALL_STATUS_ALERTING || telCallState == TelCallState::CALL_STATUS_DISCONNECTED)) { TELEPHONY_LOGI("before modify set device to EARPIECE, now not set"); return; } if (initDeviceType == AudioDeviceType::DEVICE_WIRED_HEADSET || initDeviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO || initDeviceType == AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE) { device.deviceType = initDeviceType; } TELEPHONY_LOGI("set device type, type: %{public}d", static_cast(device.deviceType)); SetAudioDevice(device); } else if (!isSetAudioDeviceByUser_ && IsVideoCall(priorVideoState) && !IsVideoCall(nextVideoState)) { device.deviceType = AudioDeviceType::DEVICE_EARPIECE; if (initDeviceType == AudioDeviceType::DEVICE_WIRED_HEADSET || initDeviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO || initDeviceType == AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE) { device.deviceType = initDeviceType; } TELEPHONY_LOGI("set device type, type: %{public}d", static_cast(device.deviceType)); SetAudioDevice(device); } } void AudioControlManager::UpdateDeviceTypeForVideoOrSatelliteCall() { sptr foregroundCall = CallObjectManager::GetForegroundCall(); if (foregroundCall == nullptr) { TELEPHONY_LOGE("call object nullptr"); return; } if (foregroundCall->GetCallType() != CallType::TYPE_IMS && foregroundCall->GetCallType() != CallType::TYPE_SATELLITE) { TELEPHONY_LOGE("other call not need control audio"); return; } AudioDevice device = { .deviceType = AudioDeviceType::DEVICE_SPEAKER, .address = { 0 }, }; AudioDeviceType initDeviceType = GetInitAudioDeviceType(); if (IsVideoCall(foregroundCall->GetVideoStateType()) || foregroundCall->GetCallType() == CallType::TYPE_SATELLITE) { if (initDeviceType == AudioDeviceType::DEVICE_WIRED_HEADSET || initDeviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO || initDeviceType == AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE) { device.deviceType = initDeviceType; } TELEPHONY_LOGI("set device type, type: %{public}d", static_cast(device.deviceType)); SetAudioDevice(device); } } void AudioControlManager::UpdateDeviceTypeForCrs() { sptr incomingCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING); if (incomingCall == nullptr) { return; } if (incomingCall->GetCrsType() == CRS_TYPE) { AudioDevice device = { .deviceType = AudioDeviceType::DEVICE_SPEAKER, .address = { 0 }, }; AudioStandard::AudioRingerMode ringMode = DelayedSingleton::GetInstance()->GetRingerMode(); if (ringMode != AudioStandard::AudioRingerMode::RINGER_MODE_NORMAL) { AudioDeviceType initDeviceType = GetInitAudioDeviceType(); if (initDeviceType == AudioDeviceType::DEVICE_WIRED_HEADSET || initDeviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) { device.deviceType = initDeviceType; } } TELEPHONY_LOGI("crs ring tone should be speaker"); SetAudioDevice(device); } } void AudioControlManager::UpdateDeviceTypeForVideoDialing() { sptr dialingCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_DIALING); if (dialingCall == nullptr) { return; } if (dialingCall->GetVideoStateType() == VideoStateType::TYPE_VIDEO) { AudioDevice device = { .deviceType = AudioDeviceType::DEVICE_SPEAKER, .address = { 0 }, }; AudioDeviceType initDeviceType = GetInitAudioDeviceType(); if (initDeviceType == AudioDeviceType::DEVICE_WIRED_HEADSET || initDeviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) { return; } TELEPHONY_LOGI("dialing video call should be speaker"); SetAudioDevice(device); } } void AudioControlManager::IncomingCallActivated(sptr &callObjectPtr) {} void AudioControlManager::IncomingCallHungUp(sptr &callObjectPtr, bool isSendSms, std::string content) { if (callObjectPtr == nullptr) { TELEPHONY_LOGE("call object ptr nullptr"); return; } StopWaitingTone(); } void AudioControlManager::HandleCallStateUpdated( sptr &callObjectPtr, TelCallState priorState, TelCallState nextState) { if (nextState == TelCallState::CALL_STATUS_ANSWERED) { TELEPHONY_LOGI("user answered, mute ringer instead of release renderer"); if (priorState == TelCallState::CALL_STATUS_INCOMING) { DelayedSingleton::GetInstance()->DeleteCall(callObjectPtr->GetCallID(), priorState); } MuteRinger(); return; } HandleNextState(callObjectPtr, nextState); if (priorState == nextState) { TELEPHONY_LOGI("prior state equals next state"); return; } HandlePriorState(callObjectPtr, priorState); } void AudioControlManager::HandleNextState(sptr &callObjectPtr, TelCallState nextState) { AudioEvent event = AudioEvent::UNKNOWN_EVENT; DelayedSingleton::GetInstance()->AddCall(callObjectPtr->GetCallID(), nextState); switch (nextState) { case TelCallState::CALL_STATUS_DIALING: event = AudioEvent::NEW_DIALING_CALL; audioInterruptState_ = AudioInterruptState::INTERRUPT_STATE_RINGING; break; case TelCallState::CALL_STATUS_ALERTING: event = AudioEvent::NEW_ALERTING_CALL; audioInterruptState_ = AudioInterruptState::INTERRUPT_STATE_RINGING; break; case TelCallState::CALL_STATUS_ACTIVE: HandleNewActiveCall(callObjectPtr); audioInterruptState_ = AudioInterruptState::INTERRUPT_STATE_ACTIVATED; break; case TelCallState::CALL_STATUS_WAITING: case TelCallState::CALL_STATUS_INCOMING: event = AudioEvent::NEW_INCOMING_CALL; audioInterruptState_ = AudioInterruptState::INTERRUPT_STATE_RINGING; break; case TelCallState::CALL_STATUS_DISCONNECTING: case TelCallState::CALL_STATUS_DISCONNECTED: if (isCrsVibrating_) { DelayedSingleton::GetInstance()->StopVibrator(); isCrsVibrating_ = false; } audioInterruptState_ = AudioInterruptState::INTERRUPT_STATE_DEACTIVATED; break; default: break; } if (event == AudioEvent::UNKNOWN_EVENT) { return; } DelayedSingleton::GetInstance()->ProcessEvent(event); } void AudioControlManager::HandlePriorState(sptr &callObjectPtr, TelCallState priorState) { AudioEvent event = AudioEvent::UNKNOWN_EVENT; DelayedSingleton::GetInstance()->DeleteCall(callObjectPtr->GetCallID(), priorState); int32_t stateNumber = DelayedSingleton::GetInstance()->GetCallNumber(priorState); switch (priorState) { case TelCallState::CALL_STATUS_DIALING: if (stateNumber == EMPTY_VALUE) { StopRingback(); // should stop ringtone while no more alerting calls event = AudioEvent::NO_MORE_DIALING_CALL; } break; case TelCallState::CALL_STATUS_ALERTING: if (stateNumber == EMPTY_VALUE) { StopRingback(); // should stop ringtone while no more alerting calls event = AudioEvent::NO_MORE_ALERTING_CALL; } break; case TelCallState::CALL_STATUS_INCOMING: case TelCallState::CALL_STATUS_WAITING: ProcessAudioWhenCallActive(callObjectPtr); event = AudioEvent::NO_MORE_INCOMING_CALL; break; case TelCallState::CALL_STATUS_ACTIVE: if (stateNumber == EMPTY_VALUE) { event = AudioEvent::NO_MORE_ACTIVE_CALL; } StopRingback(); break; case TelCallState::CALL_STATUS_HOLDING: if (stateNumber == EMPTY_VALUE) { event = AudioEvent::NO_MORE_HOLDING_CALL; } break; default: break; } if (event == AudioEvent::UNKNOWN_EVENT) { return; } DelayedSingleton::GetInstance()->ProcessEvent(event); } void AudioControlManager::ProcessAudioWhenCallActive(sptr &callObjectPtr) { if (callObjectPtr->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_ACTIVE) { if (isCrsVibrating_) { DelayedSingleton::GetInstance()->StopVibrator(); isCrsVibrating_ = false; } int ringCallCount = CallObjectManager::GetCallNumByRunningState(CallRunningState::CALL_RUNNING_STATE_RINGING); if ((CallObjectManager::GetCurrentCallNum() - ringCallCount) < MIN_MULITY_CALL_COUNT) { StopSoundtone(); PlaySoundtone(); } UpdateDeviceTypeForVideoOrSatelliteCall(); } } void AudioControlManager::HandleNewActiveCall(sptr &callObjectPtr) { CallType callType = callObjectPtr->GetCallType(); AudioEvent event = AudioEvent::UNKNOWN_EVENT; switch (callType) { case CallType::TYPE_CS: case CallType::TYPE_SATELLITE: event = AudioEvent::NEW_ACTIVE_CS_CALL; break; case CallType::TYPE_IMS: event = AudioEvent::NEW_ACTIVE_IMS_CALL; break; case CallType::TYPE_OTT: event = AudioEvent::NEW_ACTIVE_OTT_CALL; break; default: break; } if (event == AudioEvent::UNKNOWN_EVENT) { return; } DelayedSingleton::GetInstance()->ProcessEvent(event); } /** * @param device , audio device * usually called by the ui interaction , in purpose of switching to another audio device */ int32_t AudioControlManager::SetAudioDevice(const AudioDevice &device) { return SetAudioDevice(device, false); } /** * @param device , audio device * @param isByUser , call from callui or not * usually called by the ui interaction , in purpose of switching to another audio device */ int32_t AudioControlManager::SetAudioDevice(const AudioDevice &device, bool isByUser) { TELEPHONY_LOGI("set audio device, type: %{public}d", static_cast(device.deviceType)); AudioDeviceType audioDeviceType = AudioDeviceType::DEVICE_UNKNOWN; isSetAudioDeviceByUser_ = isByUser; if (CallObjectManager::HasSatelliteCallExist() && device.deviceType == AudioDeviceType::DEVICE_EARPIECE) { DelayedSingleton::GetInstance()->DialogConnectExtension("SATELLITE_CALL_NOT_SUPPORT_EARPIECE"); return CALL_ERR_AUDIO_SET_AUDIO_DEVICE_FAILED; } switch (device.deviceType) { case AudioDeviceType::DEVICE_SPEAKER: case AudioDeviceType::DEVICE_EARPIECE: case AudioDeviceType::DEVICE_WIRED_HEADSET: audioDeviceType = device.deviceType; break; case AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE: case AudioDeviceType::DEVICE_DISTRIBUTED_PHONE: case AudioDeviceType::DEVICE_DISTRIBUTED_PAD: return HandleDistributeAudioDevice(device); case AudioDeviceType::DEVICE_BLUETOOTH_SCO: { std::string address = device.address; std::unique_ptr activeBluetoothDevice = AudioStandard::AudioRoutingManager::GetInstance()->GetActiveBluetoothDevice(); if (address.empty()) { if (activeBluetoothDevice != nullptr && !activeBluetoothDevice->macAddress_.empty()) { address = activeBluetoothDevice->macAddress_; } } AudioSystemManager* audioSystemManager = AudioSystemManager::GetInstance(); int32_t ret = audioSystemManager->SetCallDeviceActive(ActiveDeviceType::BLUETOOTH_SCO, true, address); if (ret != 0) { TELEPHONY_LOGE("SetCallDeviceActive failed"); return CALL_ERR_AUDIO_SET_AUDIO_DEVICE_FAILED; } audioDeviceType = device.deviceType; break; } default: break; } if (audioDeviceType != AudioDeviceType::DEVICE_UNKNOWN) { if (DelayedSingleton::GetInstance()->IsDCallDeviceSwitchedOn()) { DelayedSingleton::GetInstance()->SwitchOffDCallDeviceSync(); } if (DelayedSingleton::GetInstance()->SwitchDevice(audioDeviceType)) { return TELEPHONY_SUCCESS; } } return CALL_ERR_AUDIO_SET_AUDIO_DEVICE_FAILED; } int32_t AudioControlManager::HandleDistributeAudioDevice(const AudioDevice &device) { if (!DelayedSingleton::GetInstance()->IsDCallDeviceSwitchedOn()) { if (DelayedSingleton::GetInstance()->SwitchOnDCallDeviceSync(device)) { return TELEPHONY_SUCCESS; } return CALL_ERR_AUDIO_SET_AUDIO_DEVICE_FAILED; } return TELEPHONY_SUCCESS; } bool AudioControlManager::PlayRingtone() { if (!ShouldPlayRingtone()) { TELEPHONY_LOGE("should not play ringtone"); return false; } ring_ = std::make_unique(); if (ring_ == nullptr) { TELEPHONY_LOGE("create ring object failed"); return false; } sptr incomingCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING); if (incomingCall == nullptr) { TELEPHONY_LOGE("incomingCall is nullptr"); return false; } CallAttributeInfo info; incomingCall->GetCallAttributeBaseInfo(info); AudioStandard::AudioRingerMode ringMode = DelayedSingleton::GetInstance()->GetRingerMode(); if (incomingCall->GetCrsType() == CRS_TYPE) { if (!isCrsVibrating_ && (ringMode != AudioStandard::AudioRingerMode::RINGER_MODE_SILENT)) { isCrsVibrating_ = (DelayedSingleton::GetInstance()->StartVibrator() == TELEPHONY_SUCCESS); } if ((ringMode == AudioStandard::AudioRingerMode::RINGER_MODE_NORMAL) || IsBtOrWireHeadPlugin()) { if (PlaySoundtone()) { TELEPHONY_LOGI("play soundtone success"); return true; } return false; } } if (ring_->Play(info.accountId) != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("play ringtone failed"); return false; } TELEPHONY_LOGI("play ringtone success"); return true; } bool AudioControlManager::IsDistributeCallSinkStatus() { std::string dcStatus = ""; auto settingHelper = SettingsDataShareHelper::GetInstance(); if (settingHelper != nullptr) { OHOS::Uri settingUri(SettingsDataShareHelper::SETTINGS_DATASHARE_URI); settingHelper->Query(settingUri, "distributed_modem_state", dcStatus); } TELEPHONY_LOGI("distributed communication modem status: %{public}s", dcStatus.c_str()); if (dcStatus != "1_sink") { return false; } return true; } bool AudioControlManager::PlaySoundtone() { if (IsDistributeCallSinkStatus()) { TELEPHONY_LOGI("distribute call sink status, no need to play sound tone"); return true; } if (soundState_ == SoundState::SOUNDING) { TELEPHONY_LOGE("should not play soundTone"); return false; } if (sound_ == nullptr) { sound_ = std::make_unique(); if (sound_ == nullptr) { TELEPHONY_LOGE("create sound object failed"); return false; } } if (sound_->Play() != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("play soundtone failed"); return false; } TELEPHONY_LOGI("play soundtone success"); return true; } bool AudioControlManager::StopSoundtone() { if (soundState_ == SoundState::STOPPED) { TELEPHONY_LOGI("soundtone already stopped"); return true; } if (sound_ == nullptr) { TELEPHONY_LOGE("sound_ is nullptr"); return false; } if (sound_->Stop() != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("stop soundtone failed"); return false; } sound_->ReleaseRenderer(); TELEPHONY_LOGI("stop soundtone success"); return true; } bool AudioControlManager::StopRingtone() { if (ringState_ == RingState::STOPPED) { TELEPHONY_LOGI("ringtone already stopped"); return true; } if (ring_ == nullptr) { TELEPHONY_LOGE("ring_ is nullptr"); return false; } if (ring_->Stop() != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("stop ringtone failed"); return false; } ring_->ReleaseRenderer(); TELEPHONY_LOGI("stop ringtone success"); return true; } /** * while audio state changed , maybe need to reinitialize the audio device * in order to get the initialization status of audio device , need to consider varieties of audio conditions */ AudioDeviceType AudioControlManager::GetInitAudioDeviceType() const { if (audioInterruptState_ == AudioInterruptState::INTERRUPT_STATE_DEACTIVATED) { return AudioDeviceType::DEVICE_DISABLE; } else { /** * Init audio device type according to the priority in different call state: * In voice call state, bluetooth sco > wired headset > earpiece > speaker * In video call state, bluetooth sco > wired headset > speaker > earpiece */ if (AudioDeviceManager::IsDistributedCallConnected()) { return AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE; } if (AudioDeviceManager::IsBtActived()) { return AudioDeviceType::DEVICE_BLUETOOTH_SCO; } if (AudioDeviceManager::IsWiredHeadsetConnected()) { return AudioDeviceType::DEVICE_WIRED_HEADSET; } sptr liveCall = CallObjectManager::GetForegroundCall(); if (liveCall != nullptr && (liveCall->GetVideoStateType() == VideoStateType::TYPE_VIDEO || liveCall->GetCallType() == CallType::TYPE_SATELLITE)) { TELEPHONY_LOGI("current video or satellite call speaker is active"); return AudioDeviceType::DEVICE_SPEAKER; } if (AudioDeviceManager::IsEarpieceAvailable()) { return AudioDeviceType::DEVICE_EARPIECE; } return AudioDeviceType::DEVICE_SPEAKER; } } /** * @param isMute , mute state * usually called by the ui interaction , mute or unmute microphone */ int32_t AudioControlManager::SetMute(bool isMute) { bool hasCall = DelayedSingleton::GetInstance()->HasCall(); if (!hasCall) { TELEPHONY_LOGE("no call exists, set mute failed"); return CALL_ERR_AUDIO_SETTING_MUTE_FAILED; } bool enabled = false; if ((DelayedSingleton::GetInstance()->HasEmergency(enabled) == TELEPHONY_SUCCESS) && enabled) { isMute = false; } if (!DelayedSingleton::GetInstance()->SetMicrophoneMute(isMute)) { TELEPHONY_LOGE("set mute failed"); return CALL_ERR_AUDIO_SETTING_MUTE_FAILED; } DelayedSingleton::GetInstance()->ReportAudioDeviceInfo(); if (frontCall_ == nullptr) { TELEPHONY_LOGE("frontCall_ is nullptr"); return TELEPHONY_ERR_LOCAL_PTR_NULL; } bool muted = DelayedSingleton::GetInstance()->IsMicrophoneMute(); frontCall_->SetMicPhoneState(muted); TELEPHONY_LOGI("SetMute success callId:%{public}d, mute:%{public}d", frontCall_->GetCallID(), muted); return TELEPHONY_SUCCESS; } int32_t AudioControlManager::MuteRinger() { sptr incomingCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING); if (incomingCall != nullptr) { if (incomingCall->GetCrsType() == CRS_TYPE) { TELEPHONY_LOGI("Mute network ring tone."); MuteNetWorkRingTone(); } } SendMuteRingEvent(); if (ringState_ == RingState::STOPPED) { TELEPHONY_LOGI("ring already stopped"); return TELEPHONY_SUCCESS; } if (ring_ == nullptr) { TELEPHONY_LOGE("ring is nullptr"); return CALL_ERR_AUDIO_SETTING_MUTE_FAILED; } if (ring_->SetMute() != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("SetMute fail"); return CALL_ERR_AUDIO_SETTING_MUTE_FAILED; } TELEPHONY_LOGI("mute ring success"); return TELEPHONY_SUCCESS; } void AudioControlManager::SendMuteRingEvent() { CallEventInfo eventInfo; eventInfo.eventId = CallAbilityEventId::EVENT_MUTE_RING; DelayedSingleton::GetInstance()->CallEventUpdated(eventInfo); } void AudioControlManager::PlayCallEndedTone(CallEndedType type) { int32_t state; DelayedSingleton::GetInstance()->GetVoIPCallState(state); if (state != static_cast(CallStateToApp::CALL_STATE_IDLE)) { TELEPHONY_LOGI("not play callEndTone when has voip call"); return; } AudioStandard::AudioRingerMode ringMode = DelayedSingleton::GetInstance()->GetRingerMode(); if (ringMode != AudioStandard::AudioRingerMode::RINGER_MODE_NORMAL) { TELEPHONY_LOGE("ringer mode is not normal"); return; } switch (type) { case CallEndedType::PHONE_IS_BUSY: PlayCallTone(ToneDescriptor::TONE_ENGAGED); break; case CallEndedType::CALL_ENDED_NORMALLY: if (toneState_ == ToneState::TONEING) { StopCallTone(); } TELEPHONY_LOGI("play call ended tone"); if (PlayCallTone(ToneDescriptor::TONE_FINISHED) != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("play call ended tone failed"); return; } toneState_ = ToneState::CALLENDED; std::this_thread::sleep_for(std::chrono::milliseconds(CALL_ENDED_PLAY_TIME)); toneState_ = ToneState::TONEING; if (StopCallTone() != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("stop call ended tone failed"); return; } break; case CallEndedType::UNKNOWN: PlayCallTone(ToneDescriptor::TONE_UNKNOWN); break; case CallEndedType::INVALID_NUMBER: PlayCallTone(ToneDescriptor::TONE_INVALID_NUMBER); break; default: break; } } std::set> AudioControlManager::GetCallList() { std::lock_guard lock(mutex_); return totalCalls_; } sptr AudioControlManager::GetCurrentActiveCall() { int32_t callId = DelayedSingleton::GetInstance()->GetCurrentActiveCall(); if (callId != INVALID_CALLID) { return GetCallBase(callId); } return nullptr; } sptr AudioControlManager::GetCallBase(int32_t callId) { sptr callBase = nullptr; std::lock_guard lock(mutex_); for (auto &call : totalCalls_) { if (call->GetCallID() == callId) { callBase = call; break; } } return callBase; } bool AudioControlManager::IsEmergencyCallExists() { std::lock_guard lock(mutex_); for (auto call : totalCalls_) { if (call->GetEmergencyState()) { return true; } } return false; } bool AudioControlManager::IsSatelliteExists() { std::lock_guard lock(mutex_); for (auto call : totalCalls_) { if (call->GetCallType() == CallType::TYPE_SATELLITE) { return true; } } return false; } AudioInterruptState AudioControlManager::GetAudioInterruptState() { return audioInterruptState_; } void AudioControlManager::SetVolumeAudible() { DelayedSingleton::GetInstance()->SetVolumeAudible(); } void AudioControlManager::SetRingState(RingState state) { ringState_ = state; } void AudioControlManager::SetSoundState(SoundState state) { soundState_ = state; } void AudioControlManager::SetToneState(ToneState state) { std::lock_guard lock(toneStateLock_); toneState_ = state; } void AudioControlManager::SetLocalRingbackNeeded(bool isNeeded) { if (isLocalRingbackNeeded_ && !isNeeded) { StopRingback(); } isLocalRingbackNeeded_ = isNeeded; } bool AudioControlManager::IsNumberAllowed(const std::string &phoneNum) { // check whether the phone number is allowed or not , should not ring if number is not allowed return true; } bool AudioControlManager::ShouldPlayRingtone() const { auto processor = DelayedSingleton::GetInstance(); int32_t alertingCallNum = processor->GetCallNumber(TelCallState::CALL_STATUS_ALERTING); int32_t incomingCallNum = processor->GetCallNumber(TelCallState::CALL_STATUS_INCOMING); if (incomingCallNum == EMPTY_VALUE || alertingCallNum > EMPTY_VALUE || ringState_ == RingState::RINGING || (soundState_ == SoundState::SOUNDING && CallObjectManager::HasIncomingCallCrsType())) { return false; } return true; } bool AudioControlManager::IsAudioActivated() const { return audioInterruptState_ == AudioInterruptState::INTERRUPT_STATE_ACTIVATED || audioInterruptState_ == AudioInterruptState::INTERRUPT_STATE_RINGING; } int32_t AudioControlManager::PlayCallTone(ToneDescriptor type) { std::lock_guard lock(toneStateLock_); if (toneState_ == ToneState::TONEING) { TELEPHONY_LOGE("should not play callTone"); return CALL_ERR_AUDIO_TONE_PLAY_FAILED; } toneState_ = ToneState::TONEING; tone_ = std::make_unique(type); if (tone_ == nullptr) { TELEPHONY_LOGE("create tone failed"); return TELEPHONY_ERR_LOCAL_PTR_NULL; } if (tone_->Play() != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("play calltone failed"); return CALL_ERR_AUDIO_TONE_PLAY_FAILED; } TELEPHONY_LOGI("play calltone success"); return TELEPHONY_SUCCESS; } int32_t AudioControlManager::StopCallTone() { std::lock_guard lock(toneStateLock_); if (toneState_ == ToneState::STOPPED) { TELEPHONY_LOGI("tone is already stopped"); return TELEPHONY_SUCCESS; } if (toneState_ == ToneState::CALLENDED) { TELEPHONY_LOGE("call ended tone is running"); return CALL_ERR_AUDIO_TONE_STOP_FAILED; } if (tone_ == nullptr) { TELEPHONY_LOGE("tone_ is nullptr"); return TELEPHONY_ERR_LOCAL_PTR_NULL; } if (tone_->Stop() != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("stop calltone failed"); return CALL_ERR_AUDIO_TONE_STOP_FAILED; } tone_->ReleaseRenderer(); toneState_ = ToneState::STOPPED; TELEPHONY_LOGI("stop call tone success"); return TELEPHONY_SUCCESS; } bool AudioControlManager::IsTonePlaying() { std::lock_guard lock(toneStateLock_); return toneState_ == ToneState::TONEING; } bool AudioControlManager::IsCurrentRinging() const { return ringState_ == RingState::RINGING; } int32_t AudioControlManager::PlayRingback() { if (!isLocalRingbackNeeded_) { return CALL_ERR_AUDIO_TONE_PLAY_FAILED; } return PlayCallTone(ToneDescriptor::TONE_RINGBACK); } int32_t AudioControlManager::StopRingback() { return StopCallTone(); } int32_t AudioControlManager::PlayWaitingTone() { return PlayCallTone(ToneDescriptor::TONE_WAITING); } int32_t AudioControlManager::StopWaitingTone() { if (tone_ != nullptr && tone_->getCurrentToneType() == ToneDescriptor::TONE_WAITING) { return StopCallTone(); } return TELEPHONY_SUCCESS; } int32_t AudioControlManager::PlayDtmfTone(char str) { ToneDescriptor dtmfTone = Tone::ConvertDigitToTone(str); std::unique_ptr tone = std::make_unique(dtmfTone); if (tone == nullptr) { TELEPHONY_LOGE("create dtmf tone failed"); return TELEPHONY_ERR_LOCAL_PTR_NULL; } if (tone->Play() != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("play dtmftone failed"); return CALL_ERR_AUDIO_TONE_PLAY_FAILED; } TELEPHONY_LOGI("play dtmftone success"); std::this_thread::sleep_for(std::chrono::milliseconds(DTMF_PLAY_TIME)); if (tone->Stop() != TELEPHONY_SUCCESS) { TELEPHONY_LOGE("stop dtmftone failed"); return CALL_ERR_AUDIO_TONE_STOP_FAILED; } tone->ReleaseRenderer(); TELEPHONY_LOGI("stop dtmf tone success"); return TELEPHONY_SUCCESS; } int32_t AudioControlManager::StopDtmfTone() { return StopCallTone(); } int32_t AudioControlManager::OnPostDialNextChar(char str) { int32_t result = PlayDtmfTone(str); if (result != TELEPHONY_SUCCESS) { return result; } return TELEPHONY_SUCCESS; } void AudioControlManager::NewCallCreated(sptr &callObjectPtr) {} void AudioControlManager::CallDestroyed(const DisconnectedDetails &details) {} bool AudioControlManager::IsSoundPlaying() { return soundState_ == SoundState::SOUNDING; } void AudioControlManager::MuteNetWorkRingTone() { bool result = DelayedSingleton::GetInstance()->SetAudioScene(AudioStandard::AudioScene::AUDIO_SCENE_DEFAULT); TELEPHONY_LOGI("Set volume mute, result: %{public}d", result); if (isCrsVibrating_) { DelayedSingleton::GetInstance()->StopVibrator(); isCrsVibrating_ = false; } } bool AudioControlManager::IsVideoCall(VideoStateType videoState) { return videoState == VideoStateType::TYPE_SEND_ONLY || videoState == VideoStateType::TYPE_RECEIVE_ONLY || videoState == VideoStateType::TYPE_VIDEO; } bool AudioControlManager::IsBtOrWireHeadPlugin() { return AudioDeviceManager::IsBtActived() || AudioDeviceManager::IsWiredHeadsetConnected(); } } // namespace Telephony } // namespace OHOS