* Copyright (C) 2021 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 "bluetooth_call_service.h"
#include "audio_device_manager.h"
#include "bluetooth_call_manager.h"
#include "call_manager_errors.h"
#include "telephony_errors.h"
#include "telephony_log_wrapper.h"
#include "telephony_permission.h"
#include "audio_control_manager.h"
#include "ffrt.h"
#include "call_superprivacy_control_manager.h"
namespace OHOS {
namespace Telephony {
const uint64_t DELAY_STOP_PLAY_TIME = 3000000;
BluetoothCallService::BluetoothCallService()
: callControlManagerPtr_(DelayedSingleton<CallControlManager>::GetInstance()),
sendDtmfState_(false), sendDtmfCallId_(ERR_ID)
{}
BluetoothCallService::~BluetoothCallService()
{}
int32_t BluetoothCallService::AnswerCall()
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
int32_t ret = AnswerCallPolicy(callId);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("AnswerCallPolicy failed!");
if (IsVoipCallExist()) {
sendEventToVoip(CallAbilityEventId::EVENT_ANSWER_VOIP_CALL);
return TELEPHONY_SUCCESS;
}
return ret;
}
sptr<CallBase> call = GetOneCallObject(callId);
if (call == nullptr) {
TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
VideoStateType videoState = call->GetVideoStateType();
if (videoState != VideoStateType::TYPE_VOICE && videoState != VideoStateType::TYPE_VIDEO) {
TELEPHONY_LOGE("get original call type!");
videoState = static_cast<VideoStateType>(call->GetOriginalCallType());
}
if (callControlManagerPtr_ != nullptr) {
auto callSuperPrivacyControlManager = DelayedSingleton<CallSuperPrivacyControlManager>::GetInstance();
if (callSuperPrivacyControlManager == nullptr) {
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
if (!callSuperPrivacyControlManager->CanCallWithSuperPrivacyPolicy()) {
DelayedSingleton<AudioControlManager>::GetInstance()->PlayWaitingTone();
ffrt::submit_h([]() {
DelayedSingleton<AudioControlManager>::GetInstance()->StopWaitingTone();
}, {}, {}, ffrt::task_attr().delay(DELAY_STOP_PLAY_TIME));
}
return callControlManagerPtr_->AnswerCall(callId, static_cast<int32_t>(videoState));
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
int32_t BluetoothCallService::RejectCall()
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
bool rejectWithMessage = false;
std::u16string textMessage = Str8ToStr16("");
int32_t ret = RejectCallPolicy(callId);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("RejectCallPolicy failed!");
if (IsVoipCallExist()) {
sendEventToVoip(CallAbilityEventId::EVENT_REJECT_VOIP_CALL);
return TELEPHONY_SUCCESS;
}
return ret;
}
if (callControlManagerPtr_ != nullptr) {
return callControlManagerPtr_->RejectCall(callId, rejectWithMessage, textMessage);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
int32_t BluetoothCallService::HangUpCall()
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
int32_t ret = HangUpPolicy(callId);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("HangUpPolicy Voip Call!");
if (IsVoipCallExist()) {
sendEventToVoip(CallAbilityEventId::EVENT_HANGUP_VOIP_CALL);
return TELEPHONY_SUCCESS;
}
DeleteOneVoipCallObject(callId);
return ret;
}
if (callId >= VOIP_CALL_MINIMUM && IsVoipCallExist()) {
sendEventToVoip(CallAbilityEventId::EVENT_HANGUP_VOIP_CALL);
DeleteOneVoipCallObject(callId);
return TELEPHONY_SUCCESS;
}
if (callControlManagerPtr_ != nullptr) {
return callControlManagerPtr_->HangUpCall(callId);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
void BluetoothCallService::sendEventToVoip(CallAbilityEventId eventId)
{
CallEventInfo eventInfo;
(void)memset_s(&eventInfo, sizeof(CallEventInfo), 0, sizeof(CallEventInfo));
eventInfo.eventId = eventId;
DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallEventUpdated(eventInfo);
}
int32_t BluetoothCallService::GetCallState()
{
if (!TelephonyPermission::CheckPermission(Permission::GET_TELEPHONY_STATE)) {
return TELEPHONY_ERR_PERMISSION_ERR;
}
TELEPHONY_LOGI("Entry BluetoothCallService GetCallState");
int32_t numActive = 0;
int32_t numHeld = 0;
int32_t callState = static_cast<int32_t>(TelCallState::CALL_STATUS_IDLE);
std::string number = "";
std::vector<int32_t> callInfo = getCallInfoNum(callState, number);
if (!callInfo.empty()) {
numActive = callInfo[0];
numHeld = callInfo[1];
}
if (IsVoipCallExist() && numActive == 0) {
GetVoipCallState(numActive, callState, number);
}
return DelayedSingleton<BluetoothCallManager>::GetInstance()->
SendBtCallState(numActive, numHeld, callState, number);
}
std::vector<int32_t> BluetoothCallService::getCallInfoNum(int32_t &callState, std::string &number)
{
int32_t numActive = GetCallNum(TelCallState::CALL_STATUS_ACTIVE, true);
int32_t numHeld = GetCallNum(TelCallState::CALL_STATUS_HOLDING, true);
int32_t numDial = GetCallNum(TelCallState::CALL_STATUS_DIALING, true);
int32_t numAlert = GetCallNum(TelCallState::CALL_STATUS_ALERTING, true);
int32_t numIncoming = GetCallNum(TelCallState::CALL_STATUS_INCOMING, true);
int32_t numWait = GetCallNum(TelCallState::CALL_STATUS_WAITING, true);
int32_t numDisconnected = GetCallNum(TelCallState::CALL_STATUS_DISCONNECTED, true);
int32_t numDisconnecting = GetCallNum(TelCallState::CALL_STATUS_DISCONNECTING, true);
if (numHeld > 0) {
callState = static_cast<int32_t>(TelCallState::CALL_STATUS_IDLE);
number = GetCallNumber(TelCallState::CALL_STATUS_HOLDING, true);
}
if (numActive > 0) {
callState = static_cast<int32_t>(TelCallState::CALL_STATUS_IDLE);
number = GetCallNumber(TelCallState::CALL_STATUS_ACTIVE, true);
}
if (numDial > 0) {
callState = static_cast<int32_t>(TelCallState::CALL_STATUS_DIALING);
number = GetCallNumber(TelCallState::CALL_STATUS_DIALING, true);
}
if (numAlert > 0) {
callState = static_cast<int32_t>(TelCallState::CALL_STATUS_ALERTING);
number = GetCallNumber(TelCallState::CALL_STATUS_ALERTING, true);
}
if (numIncoming > 0) {
callState = static_cast<int32_t>(TelCallState::CALL_STATUS_INCOMING);
number = GetCallNumber(TelCallState::CALL_STATUS_INCOMING, true);
}
if (numWait > 0) {
callState = static_cast<int32_t>(TelCallState::CALL_STATUS_INCOMING);
number = GetCallNumber(TelCallState::CALL_STATUS_WAITING, true);
}
if (numDisconnected > 0) {
callState = static_cast<int32_t>(TelCallState::CALL_STATUS_IDLE);
number = GetCallNumber(TelCallState::CALL_STATUS_DISCONNECTED, true);
}
if (numDisconnecting > 0) {
callState = static_cast<int32_t>(TelCallState::CALL_STATUS_DISCONNECTED);
number = GetCallNumber(TelCallState::CALL_STATUS_DISCONNECTING, true);
}
return {numActive, numHeld};
}
void BluetoothCallService::GetVoipCallState(int32_t &numActive, int32_t &callState, std::string &number)
{
TELEPHONY_LOGI("GetVoipCallState start,callState:%{public}d", callState);
CallAttributeInfo callAttributeInfo = GetVoipCallInfo();
if (callState == (int32_t)TelCallState::CALL_STATUS_IDLE && number == "") {
switch (callAttributeInfo.callState) {
case TelCallState::CALL_STATUS_IDLE:
numActive = 1;
break;
case TelCallState::CALL_STATUS_WAITING:
callState = (int32_t)TelCallState::CALL_STATUS_INCOMING;
break;
case TelCallState::CALL_STATUS_INCOMING:
callState = (int32_t)TelCallState::CALL_STATUS_INCOMING;
break;
case TelCallState::CALL_STATUS_ALERTING:
callState = (int32_t)TelCallState::CALL_STATUS_ALERTING;
break;
default:
TELEPHONY_LOGI("voip call state need not handle");
break;
}
number = callAttributeInfo.accountNumber;
}
if (numActive == 0 && callAttributeInfo.callState == TelCallState::CALL_STATUS_ACTIVE) {
numActive = 1;
}
TELEPHONY_LOGI("GetVoipCallState finish,callState:%{public}d, numActive:%{public}d", callState, numActive);
}
int32_t BluetoothCallService::HoldCall()
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
int32_t ret = HoldCallPolicy(callId);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("HoldCallPolicy failed!");
return ret;
}
if (callControlManagerPtr_ != nullptr) {
return callControlManagerPtr_->HoldCall(callId);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
int32_t BluetoothCallService::UnHoldCall()
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
int32_t ret = UnHoldCallPolicy(callId);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UnHoldCallPolicy failed!");
return ret;
}
if (callControlManagerPtr_ != nullptr) {
return callControlManagerPtr_->UnHoldCall(callId);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
int32_t BluetoothCallService::SwitchCall()
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
int32_t ret = SwitchCallPolicy(callId);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("SwitchCallPolicy failed!");
return ret;
}
if (callControlManagerPtr_ != nullptr) {
return callControlManagerPtr_->SwitchCall(callId);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
int32_t BluetoothCallService::StartDtmf(char str)
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
int32_t ret = StartDtmfPolicy(callId);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("StartDtmfPolicy failed!");
return ret;
}
if (callControlManagerPtr_ != nullptr) {
{
std::lock_guard<ffrt::mutex> guard(lock_);
sendDtmfState_ = true;
sendDtmfCallId_ = callId;
}
return callControlManagerPtr_->StartDtmf(callId, str);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
int32_t BluetoothCallService::StopDtmf()
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
if (callControlManagerPtr_ != nullptr) {
{
std::lock_guard<ffrt::mutex> guard(lock_);
callId = sendDtmfCallId_;
sendDtmfState_ = false;
sendDtmfCallId_ = ERR_ID;
}
return callControlManagerPtr_->StopDtmf(callId);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
int32_t BluetoothCallService::CombineConference()
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
int32_t ret = CombineConferencePolicy(callId);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("CombineConferencePolicy failed!");
return ret;
}
if (callControlManagerPtr_ != nullptr) {
return callControlManagerPtr_->CombineConference(callId);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
int32_t BluetoothCallService::SeparateConference()
{
if (!TelephonyPermission::CheckPermission(Permission::ANSWER_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
if (callControlManagerPtr_ != nullptr) {
return callControlManagerPtr_->SeparateConference(callId);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
int32_t BluetoothCallService::KickOutFromConference()
{
if (!TelephonyPermission::CheckPermission(Permission::PLACE_CALL)) {
TELEPHONY_LOGE("Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
int32_t callId = ERR_ID;
if (callControlManagerPtr_ != nullptr) {
return callControlManagerPtr_->KickOutFromConference(callId);
} else {
TELEPHONY_LOGE("callControlManagerPtr_ is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
}
std::vector<CallAttributeInfo> BluetoothCallService::GetCurrentCallList(int32_t slotId)
{
if (!TelephonyPermission::CheckPermission(Permission::GET_TELEPHONY_STATE)) {
TELEPHONY_LOGE("BluetoothCallService::GetCurrentCallList, Permission denied!");
std::vector<CallAttributeInfo> vec;
vec.clear();
return vec;
}
if (slotId < 0) {
return GetAllCallInfoList(true);
}
return GetCallInfoList(slotId, (true));
}
int32_t BluetoothCallService::AddAudioDeviceList(const std::string &address, int32_t deviceType,
const std::string &name)
{
if (!TelephonyPermission::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
TELEPHONY_LOGE("AddAudioDeviceList, Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
#ifdef SUPPORT_HEARING_AID
if (deviceType != static_cast<int32_t>(AudioDeviceType::DEVICE_NEARLINK) &&
deviceType != static_cast<int32_t>(AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID)) {
#else
if (deviceType != static_cast<int32_t>(AudioDeviceType::DEVICE_NEARLINK)) {
#endif
TELEPHONY_LOGE("AddAudioDeviceList, invalid device type!");
return TELEPHONY_ERR_ARGUMENT_INVALID;
}
DelayedSingleton<AudioDeviceManager>::GetInstance()->AddAudioDeviceList(address,
static_cast<AudioDeviceType>(deviceType), name);
return TELEPHONY_SUCCESS;
}
int32_t BluetoothCallService::RemoveAudioDeviceList(const std::string &address, int32_t deviceType)
{
if (!TelephonyPermission::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
TELEPHONY_LOGE("RemoveAudioDeviceList, Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
#ifdef SUPPORT_HEARING_AID
if (deviceType != static_cast<int32_t>(AudioDeviceType::DEVICE_NEARLINK) &&
deviceType != static_cast<int32_t>(AudioDeviceType::DEVICE_BLUETOOTH_HEARING_AID)) {
#else
if (deviceType != static_cast<int32_t>(AudioDeviceType::DEVICE_NEARLINK)) {
#endif
TELEPHONY_LOGE("RemoveAudioDeviceList, invalid device type!");
return TELEPHONY_ERR_ARGUMENT_INVALID;
}
DelayedSingleton<AudioDeviceManager>::GetInstance()->RemoveAudioDeviceList(address,
static_cast<AudioDeviceType>(deviceType));
return TELEPHONY_SUCCESS;
}
int32_t BluetoothCallService::ResetNearlinkDeviceList()
{
if (!TelephonyPermission::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
TELEPHONY_LOGE("ResetNearlinkDeviceList, Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
DelayedSingleton<AudioDeviceManager>::GetInstance()->ResetNearlinkAudioDevicesList();
return TELEPHONY_SUCCESS;
}
#ifdef SUPPORT_HEARING_AID
int32_t BluetoothCallService::ResetBtHearingAidDeviceList()
{
if (!TelephonyPermission::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
TELEPHONY_LOGE("ResetBtHearingAidDeviceList, Permission denied!");
return TELEPHONY_ERR_PERMISSION_ERR;
}
DelayedSingleton<AudioDeviceManager>::GetInstance()->ResetBtHearingAidDeviceList();
return TELEPHONY_SUCCESS;
}
#endif
}
}