* 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_device_manager.h"
#include "audio_control_manager.h"
#include "bluetooth_call_manager.h"
#include "bluetooth_device_state.h"
#include "call_ability_report_proxy.h"
#include "call_manager_hisysevent.h"
#include "call_manager_utils.h"
#include "call_object_manager.h"
#include "earpiece_device_state.h"
#include "inactive_device_state.h"
#include "speaker_device_state.h"
#include "telephony_log_wrapper.h"
#include "wired_headset_device_state.h"
#include "distributed_call_manager.h"
#include "audio_system_manager.h"
#include "audio_device_info.h"
#ifdef SUPPORT_DSOFTBUS
#include "distributed_communication_manager.h"
#endif
#include "bluetooth_call_connection.h"
namespace OHOS {
namespace Telephony {
using namespace AudioStandard;
constexpr int32_t DEVICE_ADDR_LEN = 7;
constexpr int32_t ADDR_HEAD_VALID_LEN = 5;
constexpr int32_t ADDR_TAIL_VALID_LEN = 2;
enum class AudioMode {
AUDIO_MODE_DEFAULT = 0,
AUDIO_MODE_SPEAKER = 1,
};
enum class AudioScene {
AUDIO_MODE_SCEN_CELLULAR_CALL_INCOMING = 0,
AUDIO_MODE_SCEN_CELLULAR_CALL_ALL = 1,
AUDIO_MODE_SCEN_CELLULAR_VOIP_CALL_INCOMING = 2,
AUDIO_MODE_SCEN_CELLULAR_VOIP_CALL_ALL = 3,
};
bool AudioDeviceManager::isBtScoDevEnable_ = false;
bool AudioDeviceManager::isDCallDevEnable_ = false;
bool AudioDeviceManager::isSpeakerAvailable_ = true;
bool AudioDeviceManager::isEarpieceAvailable_ = true;
bool AudioDeviceManager::isUpdateEarpieceDevice_ = false;
bool AudioDeviceManager::isWiredHeadsetConnected_ = false;
bool AudioDeviceManager::isBtScoConnected_ = false;
bool AudioDeviceManager::isDCallDevConnected_ = false;
AudioDeviceManager::AudioDeviceManager()
: audioDeviceType_(AudioDeviceType::DEVICE_UNKNOWN), currentAudioDevice_(nullptr), isAudioActivated_(false),
callAudioMode_{0, 0}
{}
AudioDeviceManager::~AudioDeviceManager()
{}
void AudioDeviceManager::Init()
{
currentAudioDevice_ = std::make_unique<InactiveDeviceState>();
if (currentAudioDevice_ == nullptr) {
TELEPHONY_LOGE("current audio device nullptr");
}
if (memset_s(&info_, sizeof(AudioDeviceInfo), 0, sizeof(AudioDeviceInfo)) != EOK) {
TELEPHONY_LOGE("memset_s address fail");
return;
}
AudioDevice speaker = {
.deviceType = AudioDeviceType::DEVICE_SPEAKER,
.address = { 0 },
};
info_.audioDeviceList.push_back(speaker);
AudioDevice earpiece = {
.deviceType = AudioDeviceType::DEVICE_EARPIECE,
.address = { 0 },
};
info_.audioDeviceList.push_back(earpiece);
if (CallManagerUtils::GetSystemParameter("const.product.devicetype", "") == "wearable") {
isEarpieceAvailable_ = false;
}
callAudioMode_.audioMode = static_cast<int32_t>(AudioMode::AUDIO_MODE_DEFAULT);
callAudioMode_.audioScene = static_cast<int32_t>(AudioScene::AUDIO_MODE_SCEN_CELLULAR_CALL_INCOMING);
}
bool AudioDeviceManager::IsSupportEarpiece()
{
std::vector<std::shared_ptr<AudioDeviceDescriptor>> audioDeviceList =
AudioStandard::AudioRoutingManager::GetInstance()->GetAvailableDevices(AudioDeviceUsage::CALL_OUTPUT_DEVICES);
for (auto& audioDevice : audioDeviceList) {
TELEPHONY_LOGI("available deviceType : %{public}d", audioDevice->deviceType_);
if (audioDevice->deviceType_ == AudioStandard::DeviceType::DEVICE_TYPE_EARPIECE) {
return true;
}
}
return false;
}
void AudioDeviceManager::UpdateEarpieceDevice()
{
if (isUpdateEarpieceDevice_ || IsSupportEarpiece()) {
isUpdateEarpieceDevice_ = true;
return;
}
isUpdateEarpieceDevice_ = true;
std::lock_guard<ffrt::mutex> lock(infoMutex_);
std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
while (it != info_.audioDeviceList.end()) {
if (it->deviceType == AudioDeviceType::DEVICE_EARPIECE) {
it = info_.audioDeviceList.erase(it);
TELEPHONY_LOGI("not support Earpice, remove Earpice device success");
return;
} else {
++it;
}
}
}
void AudioDeviceManager::UpdateBluetoothDeviceName(const std::string &macAddress, const std::string &deviceName)
{
if (!UpdateDeviceName(macAddress, deviceName, AudioDeviceType::DEVICE_BLUETOOTH_SCO)) {
if (!UpdateDeviceName(macAddress, deviceName, AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID)) {
TELEPHONY_LOGE("Failed to update Bluetooth device name for both types");
}
}
}
void AudioDeviceManager::UpdateNearlinkDeviceName(const std::string &macAddress, const std::string &deviceName)
{
if (!UpdateDeviceName(macAddress, deviceName, AudioDeviceType::DEVICE_NEARLINK)) {
TELEPHONY_LOGE("Failed to update Nearlink device name");
}
}
bool AudioDeviceManager::UpdateDeviceName(const std::string &macAddress, const std::string &deviceName,
AudioDeviceType deviceType)
{
std::lock_guard<ffrt::mutex> lock(infoMutex_);
for (auto &device : info_.audioDeviceList) {
if (device.address == macAddress && (device.deviceType == deviceType)) {
if (deviceName.length() > kMaxDeviceNameLen) {
TELEPHONY_LOGE("deviceName is too long");
return false;
}
if (memset_s(device.deviceName, sizeof(device.deviceName), 0, sizeof(device.deviceName)) != EOK) {
TELEPHONY_LOGE("memset_s fail");
return false;
}
if (memcpy_s(device.deviceName, kMaxDeviceNameLen, deviceName.c_str(), deviceName.length()) != EOK) {
TELEPHONY_LOGE("memcpy_s deviceName fail");
return false;
}
TELEPHONY_LOGI("UpdateDeviceName for type %d", static_cast<int>(deviceType));
ReportAudioDeviceInfo();
return true;
}
}
return false;
}
void AudioDeviceManager::AddAudioDeviceList(const std::string &address, AudioDeviceType deviceType,
const std::string &deviceName)
{
std::lock_guard<ffrt::mutex> lock(infoMutex_);
std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
while (it != info_.audioDeviceList.end()) {
if (it->address == address && it->deviceType == deviceType) {
TELEPHONY_LOGI("device is already existenced");
return;
}
if (deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET && it->deviceType == AudioDeviceType::DEVICE_EARPIECE) {
it = info_.audioDeviceList.erase(it);
TELEPHONY_LOGI("remove Earpiece device success");
} else {
++it;
}
}
AudioDevice audioDevice;
if (memset_s(&audioDevice, sizeof(AudioDevice), 0, sizeof(AudioDevice)) != EOK) {
TELEPHONY_LOGE("memset_s fail");
return;
}
audioDevice.deviceType = deviceType;
if (address.length() > kMaxAddressLen) {
TELEPHONY_LOGE("address is too long");
return;
}
if (memcpy_s(audioDevice.address, kMaxAddressLen, address.c_str(), address.length()) != EOK) {
TELEPHONY_LOGE("memcpy_s address fail");
return;
}
if (deviceName.length() > kMaxDeviceNameLen) {
TELEPHONY_LOGE("deviceName is too long");
return;
}
if (memcpy_s(audioDevice.deviceName, kMaxDeviceNameLen, deviceName.c_str(), deviceName.length()) != EOK) {
TELEPHONY_LOGE("memcpy_s deviceName fail");
return;
}
info_.audioDeviceList.push_back(audioDevice);
if (deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET) {
SetDeviceAvailable(AudioDeviceType::DEVICE_WIRED_HEADSET, true);
}
if (deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
SetDeviceAvailable(AudioDeviceType::DEVICE_BLUETOOTH_SCO, true);
}
if (IsDistributedAudioDeviceType(deviceType)) {
SetDeviceAvailable(deviceType, true);
}
ReportAudioDeviceInfo();
TELEPHONY_LOGI("AddAudioDeviceList success");
}
void AudioDeviceManager::RemoveAudioDeviceList(const std::string &address, AudioDeviceType deviceType)
{
std::lock_guard<ffrt::mutex> lock(infoMutex_);
bool needAddEarpiece = true;
std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
while (it != info_.audioDeviceList.end()) {
if (it->deviceType == AudioDeviceType::DEVICE_EARPIECE) {
needAddEarpiece = false;
}
if (it->address == address && it->deviceType == deviceType) {
it = info_.audioDeviceList.erase(it);
} else {
++it;
}
}
bool wiredHeadsetExist = false;
bool blueToothScoExist = false;
for (auto &elem : info_.audioDeviceList) {
if (elem.deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET) {
wiredHeadsetExist = true;
}
if (elem.deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
blueToothScoExist = true;
}
}
if (deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET && !wiredHeadsetExist) {
SetDeviceAvailable(AudioDeviceType::DEVICE_WIRED_HEADSET, false);
}
if (deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO && !blueToothScoExist) {
SetDeviceAvailable(AudioDeviceType::DEVICE_BLUETOOTH_SCO, false);
}
if (IsDistributedAudioDeviceType(deviceType)) {
SetDeviceAvailable(deviceType, false);
}
if (needAddEarpiece && deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET && !wiredHeadsetExist) {
AddEarpiece();
}
sptr<CallBase> liveCall = CallObjectManager::GetAudioLiveCall();
if (liveCall != nullptr && (liveCall->GetVideoStateType() == VideoStateType::TYPE_VIDEO ||
liveCall->GetCallType() == CallType::TYPE_SATELLITE)) {
DelayedSingleton<AudioControlManager>::GetInstance()->UpdateDeviceType();
}
ReportAudioDeviceInfo();
TELEPHONY_LOGI("RemoveAudioDeviceList success");
}
void AudioDeviceManager::AddEarpiece()
{
if (!IsSupportEarpiece()) {
TELEPHONY_LOGI("not support Earpiece device");
return;
}
AudioDevice audioDevice = {
.deviceType = AudioDeviceType::DEVICE_EARPIECE,
.address = { 0 },
};
info_.audioDeviceList.push_back(audioDevice);
TELEPHONY_LOGI("add Earpiece device success");
}
void AudioDeviceManager::ResetBtAudioDevicesList()
{
std::lock_guard<ffrt::mutex> lock(infoMutex_);
std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
bool hadBtActived = false;
while (it != info_.audioDeviceList.end()) {
if (it->deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
hadBtActived = true;
it = info_.audioDeviceList.erase(it);
} else {
++it;
}
}
SetDeviceAvailable(AudioDeviceType::DEVICE_BLUETOOTH_SCO, false);
if (hadBtActived) {
ReportAudioDeviceInfo();
}
TELEPHONY_LOGI("ResetBtAudioDevicesList success");
}
void AudioDeviceManager::ResetDistributedCallDevicesList()
{
std::lock_guard<ffrt::mutex> lock(infoMutex_);
std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
while (it != info_.audioDeviceList.end()) {
if (IsDistributedAudioDeviceType(it->deviceType)) {
it = info_.audioDeviceList.erase(it);
} else {
++it;
}
}
SetDeviceAvailable(AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE, false);
SetDeviceAvailable(AudioDeviceType::DEVICE_DISTRIBUTED_PHONE, false);
SetDeviceAvailable(AudioDeviceType::DEVICE_DISTRIBUTED_PAD, false);
SetDeviceAvailable(AudioDeviceType::DEVICE_DISTRIBUTED_PC, false);
DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportAudioDeviceChange(info_);
TELEPHONY_LOGI("Reset Distributed Audio Devices List success");
}
void AudioDeviceManager::ResetNearlinkAudioDevicesList()
{
std::unique_lock<ffrt::mutex> lock(infoMutex_);
std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
bool hadNearlinkActived = false;
while (it != info_.audioDeviceList.end()) {
if (it->deviceType == AudioDeviceType::DEVICE_NEARLINK) {
hadNearlinkActived = true;
it = info_.audioDeviceList.erase(it);
} else {
++it;
}
}
if (hadNearlinkActived) {
ReportAudioDeviceInfo();
}
lock.unlock();
if (audioDeviceType_ == AudioDeviceType::DEVICE_NEARLINK) {
TELEPHONY_LOGI("Nearlink SA removed, init audio device");
ProcessEvent(AudioEvent::INIT_AUDIO_DEVICE);
}
TELEPHONY_LOGI("ResetNearlinkAudioDevicesList success");
}
#ifdef SUPPORT_HEARING_AID
void AudioDeviceManager::ResetBtHearingAidDeviceList()
{
std::unique_lock<ffrt::mutex> lock(infoMutex_);
std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
bool hadBtHearingAidActived = false;
while (it != info_.audioDeviceList.end()) {
if (it->deviceType == AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID) {
hadBtHearingAidActived = true;
it = info_.audioDeviceList.erase(it);
} else {
++it;
}
}
if (hadBtHearingAidActived) {
ReportAudioDeviceInfo();
}
lock.unlock();
if (audioDeviceType_ == AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID) {
TELEPHONY_LOGI("Bluetooth SA removed, init audio device");
ProcessEvent(AudioEvent::INIT_AUDIO_DEVICE);
}
TELEPHONY_LOGI("ResetBtHearingAidDeviceList success");
}
#endif
bool AudioDeviceManager::InitAudioDevice()
{
auto device = DelayedSingleton<AudioControlManager>::GetInstance()->GetInitAudioDeviceType();
return SwitchDevice(device);
}
bool AudioDeviceManager::ProcessEvent(AudioEvent event)
{
bool result = false;
switch (event) {
case AudioEvent::AUDIO_ACTIVATED:
case AudioEvent::AUDIO_RINGING:
if (!isAudioActivated_) {
isAudioActivated_ = true;
AudioDevice device = {
.deviceType = AudioDeviceType::DEVICE_EARPIECE,
.address = { 0 },
};
if (DelayedSingleton<AudioProxy>::GetInstance()->GetPreferredOutputAudioDevice(device) !=
TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("current audio device nullptr");
return false;
}
SetCurrentAudioDevice(device.deviceType);
}
break;
case AudioEvent::AUDIO_DEACTIVATED:
if (isAudioActivated_) {
isAudioActivated_ = false;
result = InitAudioDevice();
}
break;
case AudioEvent::INIT_AUDIO_DEVICE:
result = InitAudioDevice();
break;
case AudioEvent::WIRED_HEADSET_DISCONNECTED: {
if (!isAudioActivated_) {
TELEPHONY_LOGE("call is not active, no need to connect sco");
return false;
}
CheckAndSwitchDistributedAudioDevice();
break;
}
default:
break;
}
return result;
}
bool AudioDeviceManager::SwitchDevice(AudioDeviceType device, bool isSetAudioDeviceByUser)
{
bool result = false;
std::lock_guard<ffrt::mutex> lock(mutex_);
switch (device) {
case AudioDeviceType::DEVICE_EARPIECE:
result = EnableEarpiece(isSetAudioDeviceByUser);
break;
case AudioDeviceType::DEVICE_SPEAKER:
result = EnableSpeaker(isSetAudioDeviceByUser);
break;
case AudioDeviceType::DEVICE_WIRED_HEADSET:
result = EnableWiredHeadset(isSetAudioDeviceByUser);
break;
case AudioDeviceType::DEVICE_BLUETOOTH_SCO:
result = EnableBtSco();
break;
case AudioDeviceType::DEVICE_DISABLE:
result = DisableAll();
break;
case AudioDeviceType::DEVICE_NEARLINK:
result = EnableNearlink();
break;
#ifdef SUPPORT_HEARING_AID
case AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID:
result = EnableBtHearingAid();
break;
#endif
default:
break;
}
TELEPHONY_LOGI("switch device lock release");
return result;
}
bool AudioDeviceManager::EnableSpeaker(bool isSetAudioDeviceByUser)
{
if (isSpeakerAvailable_ && DelayedSingleton<AudioProxy>::GetInstance()->SetSpeakerDevActive(
true, isSetAudioDeviceByUser)) {
TELEPHONY_LOGI("speaker enabled , current audio device : speaker");
SetCurrentAudioDevice(AudioDeviceType::DEVICE_SPEAKER);
return true;
}
TELEPHONY_LOGI("enable speaker device failed");
return false;
}
bool AudioDeviceManager::EnableEarpiece(bool isSetAudioDeviceByUser)
{
if (isEarpieceAvailable_ && DelayedSingleton<AudioProxy>::GetInstance()->SetEarpieceDevActive(
isSetAudioDeviceByUser)) {
TELEPHONY_LOGI("earpiece enabled , current audio device : earpiece");
SetCurrentAudioDevice(AudioDeviceType::DEVICE_EARPIECE);
return true;
}
TELEPHONY_LOGI("enable earpiece device failed");
return false;
}
bool AudioDeviceManager::EnableWiredHeadset(bool isSetAudioDeviceByUser)
{
if (isWiredHeadsetConnected_ && DelayedSingleton<AudioProxy>::GetInstance()->SetWiredHeadsetDevActive(
isSetAudioDeviceByUser)) {
TELEPHONY_LOGI("wired headset enabled , current audio device : wired headset");
SetCurrentAudioDevice(AudioDeviceType::DEVICE_WIRED_HEADSET);
return true;
}
TELEPHONY_LOGI("enable wired headset device failed");
return false;
}
bool AudioDeviceManager::EnableBtSco()
{
if (IsBtActived()) {
TELEPHONY_LOGI("bluetooth sco enabled , current audio device : bluetooth sco");
SetCurrentAudioDevice(AudioDeviceType::DEVICE_BLUETOOTH_SCO);
return true;
}
TELEPHONY_LOGI("enable bluetooth sco device failed");
return false;
}
bool AudioDeviceManager::EnableNearlink()
{
AudioDevice device;
if (IsNearlinkActived(device)) {
TELEPHONY_LOGI("nearlink enabled , current audio device : nearlink");
SetCurrentAudioDevice(AudioDeviceType::DEVICE_NEARLINK);
return true;
}
TELEPHONY_LOGI("enable nearlink device failed");
return false;
}
#ifdef SUPPORT_HEARING_AID
bool AudioDeviceManager::EnableBtHearingAid()
{
AudioDevice device;
if (IsBtHearingAidActived(device)) {
TELEPHONY_LOGI("bt hearing aid enabled , current audio device : bt hearing aid");
SetCurrentAudioDevice(AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID);
return true;
}
TELEPHONY_LOGI("enable bt hearing aid device failed");
return false;
}
#endif
bool AudioDeviceManager::DisableAll()
{
audioDeviceType_ = AudioDeviceType::DEVICE_UNKNOWN;
isBtScoDevEnable_ = false;
isDCallDevEnable_ = false;
isWiredHeadsetDevEnable_ = false;
isSpeakerDevEnable_ = false;
isEarpieceDevEnable_ = false;
currentAudioDevice_ = std::make_unique<InactiveDeviceState>();
if (currentAudioDevice_ == nullptr) {
TELEPHONY_LOGE("make_unique InactiveDeviceState failed");
return false;
}
TELEPHONY_LOGI("current audio device : all audio devices disabled");
return true;
}
void AudioDeviceManager::SetCurrentAudioDevice(AudioDeviceType deviceType)
{
TELEPHONY_LOGI("set current audio device, deviceType: %{public}d.", deviceType);
if (!IsDistributedAudioDeviceType(deviceType) && IsDistributedAudioDeviceType(audioDeviceType_)) {
DelayedSingleton<DistributedCallManager>::GetInstance()->SwitchOffDCallDeviceSync();
}
if (deviceType == AudioDeviceType::DEVICE_EARPIECE && CallObjectManager::HasSatelliteCallExist()) {
audioDeviceType_ = AudioDeviceType::DEVICE_SPEAKER;
AudioStandard::AudioSystemManager::GetInstance()->
SetDeviceActive(AudioStandard::DeviceType::DEVICE_TYPE_SPEAKER, true);
return;
}
AudioDevice device = {
.deviceType = deviceType,
.address = { 0 },
};
SetCurrentAudioDevice(device);
}
bool AudioDeviceManager::SetVirtualCall(bool isVirtual)
{
bool res = AudioStandard::AudioSystemManager::GetInstance()->SetVirtualCall(isVirtual);
TELEPHONY_LOGI("Virtualcall SetVirtualCall: %{public}d, res: %{public}d.", isVirtual, res);
return res;
}
bool AudioDeviceManager::GetVirtualCall()
{
bool res = AudioStandard::AudioSystemManager::GetInstance()->GetVirtualCall();
TELEPHONY_LOGI("Virtualcall GetVirtualCall res: %{public}d.", res);
return res;
}
void AudioDeviceManager::SetCurrentAudioDevice(const AudioDevice &device)
{
AudioDeviceType deviceType = device.deviceType;
TELEPHONY_LOGI("set current audio device, audioDeviceType = %{public}d.", deviceType);
if (!IsDistributedAudioDeviceType(deviceType) && IsDistributedAudioDeviceType(audioDeviceType_)) {
DelayedSingleton<DistributedCallManager>::GetInstance()->SwitchOffDCallDeviceSync();
}
audioDeviceType_ = deviceType;
ReportAudioDeviceChange(device);
}
bool AudioDeviceManager::CheckAndSwitchDistributedAudioDevice()
{
TELEPHONY_LOGI("check and switch distributed audio device.");
std::lock_guard<ffrt::mutex> lock(infoMutex_);
DelayedSingleton<DistributedCallManager>::GetInstance()->SetCallState(true);
std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
while (it != info_.audioDeviceList.end()) {
if (it->deviceType == AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE
&& AudioProxy::IsDistributedPreferredOutputAudioDevice()) {
DelayedSingleton<DistributedCallManager>::GetInstance()->SwitchOnDCallDeviceAsync(*it);
return true;
} else {
++it;
}
}
return false;
}
void AudioDeviceManager::OnActivedCallDisconnected()
{
DelayedSingleton<DistributedCallManager>::GetInstance()->SetCallState(false);
DelayedSingleton<DistributedCallManager>::GetInstance()->DealDisconnectCall();
}
int32_t AudioDeviceManager::ReportAudioDeviceChange(const AudioDevice &device)
{
if (audioDeviceType_ == AudioDeviceType::DEVICE_UNKNOWN) {
audioDeviceType_ = DelayedSingleton<AudioControlManager>::GetInstance()->GetInitAudioDeviceType();
}
info_.currentAudioDevice.deviceType = audioDeviceType_;
std::string address = device.address;
std::string deviceName = device.deviceName;
if (audioDeviceType_ == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
UpdateBtDevice(address, deviceName);
}
#ifdef SUPPORT_DSOFTBUS
else if (DelayedSingleton<DistributedCommunicationManager>::GetInstance()->IsDistributedDev(device)) {
TELEPHONY_LOGI("audio device is distributed communication dev");
}
#endif
else if (IsDistributedAudioDeviceType(audioDeviceType_)) {
address = DelayedSingleton<DistributedCallManager>::GetInstance()->GetConnectedDCallDeviceAddr();
} else if (audioDeviceType_ == AudioDeviceType::DEVICE_NEARLINK) {
UpdateNearlinkDevice(address, deviceName);
}
#ifdef SUPPORT_HEARING_AID
else if (audioDeviceType_ == AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID) {
UpdateBtHearingAidDevice(address, deviceName);
}
#endif
return CopyDeviceData(address, deviceName);
}
int32_t AudioDeviceManager::CopyDeviceData(const std::string &address, const std::string &deviceName)
{
if (address.length() > kMaxAddressLen) {
TELEPHONY_LOGE("address is not too long");
return TELEPHONY_ERR_ARGUMENT_INVALID;
}
if (memset_s(info_.currentAudioDevice.address, kMaxAddressLen + 1, 0, kMaxAddressLen + 1) != EOK) {
TELEPHONY_LOGE("failed to memset_s currentAudioDevice.address");
return TELEPHONY_ERR_MEMSET_FAIL;
}
if (memcpy_s(info_.currentAudioDevice.address, kMaxAddressLen, address.c_str(), address.length()) != EOK) {
TELEPHONY_LOGE("memcpy_s address fail");
return TELEPHONY_ERR_MEMCPY_FAIL;
}
if (deviceName.length() > kMaxDeviceNameLen) {
TELEPHONY_LOGE("deviceName is too long");
return TELEPHONY_ERR_ARGUMENT_INVALID;
}
if (memset_s(info_.currentAudioDevice.deviceName, kMaxDeviceNameLen + 1, 0, kMaxDeviceNameLen + 1) != EOK) {
TELEPHONY_LOGE("failed to memset_s currentAudioDevice.deviceName");
return TELEPHONY_ERR_MEMSET_FAIL;
}
if (memcpy_s(info_.currentAudioDevice.deviceName, kMaxDeviceNameLen,
deviceName.c_str(), deviceName.length()) != EOK) {
TELEPHONY_LOGE("memcpy_s deviceName fail");
return TELEPHONY_ERR_MEMCPY_FAIL;
}
return ReportAudioDeviceInfo();
}
void AudioDeviceManager::UpdateBtDevice(std::string &address, std::string &deviceName)
{
if (!address.empty() && !deviceName.empty()) {
return;
}
std::shared_ptr<AudioStandard::AudioDeviceDescriptor> activeBluetoothDevice =
AudioStandard::AudioRoutingManager::GetInstance()->GetActiveBluetoothDevice();
if (activeBluetoothDevice != nullptr && !activeBluetoothDevice->macAddress_.empty()) {
address = activeBluetoothDevice->macAddress_;
deviceName = activeBluetoothDevice->deviceName_;
}
}
void AudioDeviceManager::UpdateNearlinkDevice(std::string &address, std::string &deviceName)
{
if (!address.empty() && !deviceName.empty()) {
return;
}
AudioDevice device;
if (!IsNearlinkActived(device)) {
TELEPHONY_LOGE("Get active nearlink device failed.");
return;
}
address = device.address;
deviceName = device.deviceName;
}
#ifdef SUPPORT_HEARING_AID
void AudioDeviceManager::UpdateBtHearingAidDevice(std::string &address, std::string &deviceName)
{
if (!address.empty() && !deviceName.empty()) {
return;
}
AudioDevice device;
if (!IsBtHearingAidActived(device)) {
TELEPHONY_LOGE("Get active bt hearing aid device failed.");
return;
}
address = device.address;
deviceName = device.deviceName;
}
#endif
int32_t AudioDeviceManager::ReportAudioDeviceInfo()
{
sptr<CallBase> liveCall = CallObjectManager::GetAudioLiveCall();
return ReportAudioDeviceInfo(liveCall);
}
std::string AudioDeviceManager::ConvertAddress()
{
std::string addr = info_.currentAudioDevice.address;
if (info_.currentAudioDevice.deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO ||
info_.currentAudioDevice.deviceType == AudioDeviceType::DEVICE_NEARLINK
#ifdef SUPPORT_HEARING_AID
|| info_.currentAudioDevice.deviceType == AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID
#endif
) {
if (!addr.empty() && addr.length() > DEVICE_ADDR_LEN) {
return (addr.substr(0, ADDR_HEAD_VALID_LEN) + ":*:*:*:" +
addr.substr(addr.length() - ADDR_TAIL_VALID_LEN));
}
} else {
addr = "";
}
return addr;
}
int32_t AudioDeviceManager::ReportAudioDeviceInfo(sptr<CallBase> call)
{
if (call == nullptr) {
TELEPHONY_LOGE("call is nullptr.");
return TELEPHONY_ERR_ARGUMENT_NULL;
}
info_.callId = call->GetCallID();
CallType currentCallType = call->GetCallType();
TelCallState currentTelCallState = call->GetTelCallState();
if (currentCallType == CallType::TYPE_VOIP || currentCallType == CallType::TYPE_BLUETOOTH) {
info_.isMuted = call->IsMuted();
} else {
info_.isMuted = DelayedSingleton<AudioProxy>::GetInstance()->IsMicrophoneMute();
}
if (currentCallType == CallType::TYPE_VOIP) {
info_.isMicDisabled = call->IsMicDisabled();
}
AudioDeviceType deviceType = info_.currentAudioDevice.deviceType;
if (currentCallType == CallType::TYPE_BLUETOOTH &&
(currentTelCallState == TelCallState::CALL_STATUS_ACTIVE ||
currentTelCallState == TelCallState::CALL_STATUS_DIALING ||
currentTelCallState == TelCallState::CALL_STATUS_ALERTING)) {
bool state = DelayedSingleton<BluetoothCallConnection>::GetInstance()->GetBtCallScoConnected();
if (state) {
info_.currentAudioDevice.deviceType = AudioDeviceType::DEVICE_SPEAKER;
} else {
info_.currentAudioDevice.deviceType = AudioDeviceType::DEVICE_EARPIECE;
}
}
TELEPHONY_LOGI("report audio device info, currentAudioDeviceType:%{public}d, "
"mute:%{public}d, mic disabled:%{public}d, callId:%{public}d",
info_.currentAudioDevice.deviceType, info_.isMuted, info_.isMicDisabled, info_.callId);
CallManagerHisysevent::RecordVoipProcedure((call != nullptr) ? call->GetCallID() : -1,
VoipProcedureEvent::CALLMANAGER_HANDLE_AUDIO_CHANGE,
static_cast<int32_t>(info_.currentAudioDevice.deviceType));
int32_t ret = DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportAudioDeviceChange(info_);
info_.currentAudioDevice.deviceType = deviceType;
return ret;
}
AudioDeviceType AudioDeviceManager::GetCurrentAudioDevice()
{
return audioDeviceType_;
}
bool AudioDeviceManager::IsEarpieceDevEnable()
{
return isEarpieceDevEnable_;
}
bool AudioDeviceManager::IsWiredHeadsetDevEnable()
{
return isWiredHeadsetDevEnable_;
}
bool AudioDeviceManager::IsSpeakerDevEnable()
{
return isSpeakerDevEnable_;
}
bool AudioDeviceManager::IsBtScoDevEnable()
{
return isBtScoDevEnable_;
}
bool AudioDeviceManager::IsDCallDevEnable()
{
return isDCallDevEnable_;
}
bool AudioDeviceManager::IsBtScoConnected()
{
return isBtScoConnected_;
}
bool AudioDeviceManager::IsBtActived()
{
std::shared_ptr<AudioStandard::AudioDeviceDescriptor> activeBluetoothDevice =
AudioStandard::AudioRoutingManager::GetInstance()->GetActiveBluetoothDevice();
if (activeBluetoothDevice != nullptr && !activeBluetoothDevice->macAddress_.empty()) {
TELEPHONY_LOGI("has actived bt device");
return true;
}
return false;
}
bool AudioDeviceManager::IsNearlinkActived(AudioDevice &device)
{
if (DelayedSingleton<AudioProxy>::GetInstance()->GetPreferredOutputAudioDevice(device) != TELEPHONY_SUCCESS) {
return false;
}
if (device.deviceType != AudioDeviceType::DEVICE_NEARLINK || strlen(device.address) == 0) {
return false;
}
return true;
}
#ifdef SUPPORT_HEARING_AID
bool AudioDeviceManager::IsBtHearingAidActived(AudioDevice &device)
{
if (DelayedSingleton<AudioProxy>::GetInstance()->GetPreferredOutputAudioDevice(device) != TELEPHONY_SUCCESS) {
return false;
}
if (device.deviceType != AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID || strlen(device.address) == 0) {
return false;
}
return true;
}
#endif
bool AudioDeviceManager::IsDistributedCallConnected()
{
return isDCallDevConnected_;
}
bool AudioDeviceManager::IsWiredHeadsetConnected()
{
return isWiredHeadsetConnected_;
}
bool AudioDeviceManager::IsEarpieceAvailable()
{
return isEarpieceAvailable_;
}
bool AudioDeviceManager::IsSpeakerAvailable()
{
return isSpeakerAvailable_;
}
bool AudioDeviceManager::IsDistributedAudioDeviceType(AudioDeviceType deviceType)
{
if (((deviceType == AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE) ||
(deviceType == AudioDeviceType::DEVICE_DISTRIBUTED_PHONE) ||
(deviceType == AudioDeviceType::DEVICE_DISTRIBUTED_PAD) ||
(deviceType == AudioDeviceType::DEVICE_DISTRIBUTED_PC))) {
return true;
}
return false;
}
void AudioDeviceManager::SetDeviceAvailable(AudioDeviceType deviceType, bool available)
{
switch (deviceType) {
case AudioDeviceType::DEVICE_SPEAKER:
isSpeakerAvailable_ = available;
break;
case AudioDeviceType::DEVICE_EARPIECE:
isEarpieceAvailable_ = available;
break;
case AudioDeviceType::DEVICE_BLUETOOTH_SCO:
isBtScoConnected_ = available;
break;
case AudioDeviceType::DEVICE_WIRED_HEADSET:
isWiredHeadsetConnected_ = available;
break;
case AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE:
case AudioDeviceType::DEVICE_DISTRIBUTED_PHONE:
case AudioDeviceType::DEVICE_DISTRIBUTED_PAD:
case AudioDeviceType::DEVICE_DISTRIBUTED_PC:
isDCallDevConnected_ = available;
break;
default:
break;
}
}
bool AudioDeviceManager::IsRemoteDevicesConnected()
{
AudioDevice device = {
.deviceType = AudioDeviceType::DEVICE_EARPIECE,
.address = { 0 },
};
return IsBtActived() || IsWiredHeadsetConnected() || IsNearlinkActived(device);
}
void AudioDeviceManager::UpdateCurrentAudioDevice()
{
AudioDevice device = {
.deviceType = AudioDeviceType::DEVICE_EARPIECE,
.address = { 0 },
};
if (DelayedSingleton<AudioProxy>::GetInstance()->GetPreferredOutputAudioDevice(device) == TELEPHONY_SUCCESS) {
SetCurrentAudioDevice(device);
}
}
int32_t AudioDeviceManager::SetCallAudioMode(const CallAudioMode &callAudioMode)
{
std::lock_guard<ffrt::mutex> lock(audioModeMutex_);
callAudioMode_ = callAudioMode;
TELEPHONY_LOGI("audioMode is %{public}d, audioScene is %{public}d",
callAudioMode_.audioMode, callAudioMode_.audioScene);
return TELEPHONY_SUCCESS;
}
void AudioDeviceManager::SetAudioDeviceByAudioMode(bool isVoipCall, bool isIncomingCall)
{
if (isVoipCall) {
return;
}
std::lock_guard<ffrt::mutex> lock(audioModeMutex_);
TELEPHONY_LOGI("audioMode is %{public}d, audioScene is %{public}d",
callAudioMode_.audioMode, callAudioMode_.audioScene);
if (!isIncomingCall && ((callAudioMode_.audioScene ==
(int32_t)AudioScene::AUDIO_MODE_SCEN_CELLULAR_CALL_INCOMING) ||
(callAudioMode_.audioScene == static_cast<int32_t>(AudioScene::AUDIO_MODE_SCEN_CELLULAR_VOIP_CALL_INCOMING)))) {
return;
}
if (callAudioMode_.audioMode == static_cast<int32_t>(AudioMode::AUDIO_MODE_SPEAKER)
&& !IsRemoteDevicesConnected()) {
AudioDevice device = {
.deviceType = AudioDeviceType::DEVICE_SPEAKER,
.address = { 0 },
};
auto audioControlManager = DelayedSingleton<AudioControlManager>::GetInstance();
if (audioControlManager != nullptr) {
audioControlManager->SetAudioDevice(device);
}
}
}
void AudioDeviceManager::SetSpeakerDeactive()
{
std::lock_guard<ffrt::mutex> lock(audioModeMutex_);
if (callAudioMode_.audioMode != static_cast<int32_t>(AudioMode::AUDIO_MODE_SPEAKER)) {
TELEPHONY_LOGI("answer call set speaker deactive");
auto audioProxy = DelayedSingleton<AudioProxy>::GetInstance();
if (audioProxy != nullptr) {
audioProxy->SetSpeakerDevActive(false);
}
}
}
bool AudioDeviceManager::IsSpeakerMode()
{
std::lock_guard<ffrt::mutex> lock(audioModeMutex_);
return callAudioMode_.audioMode == static_cast<int32_t>(AudioMode::AUDIO_MODE_SPEAKER);
}
}
}