* 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 "call_object_manager.h"
#include "call_connect_ability.h"
#include "call_control_manager.h"
#include "call_manager_errors.h"
#include "call_number_utils.h"
#include "call_wired_headset.h"
#include "conference_base.h"
#include "ims_conference.h"
#include "report_call_info_handler.h"
#include "telephony_log_wrapper.h"
#include "voip_call.h"
#include "fold_status_manager.h"
namespace OHOS {
namespace Telephony {
std::list<sptr<CallBase>> CallObjectManager::callObjectPtrList_;
std::map<int32_t, CallAttributeInfo> CallObjectManager::voipCallObjectList_;
ffrt::mutex CallObjectManager::listMutex_;
int32_t CallObjectManager::callId_ = CALL_START_ID;
ffrt::condition_variable CallObjectManager::cv_;
bool CallObjectManager::isFirstDialCallAdded_ = false;
bool CallObjectManager::needWaitHold_ = false;
CellularCallInfo CallObjectManager::dialCallInfo_;
constexpr int32_t CRS_TYPE = 2;
constexpr uint64_t DISCONNECT_DELAY_TIME = 2000000;
static constexpr const char *VIDEO_RING_PATH_FIX_TAIL = ".mp4";
constexpr int32_t VIDEO_RING_PATH_FIX_TAIL_LENGTH = 4;
static constexpr const char *SYSTEM_VIDEO_RING = "system_video_ring";
CallObjectManager::CallObjectManager()
{
}
CallObjectManager::~CallObjectManager() {}
int32_t CallObjectManager::AddOneCallObject(sptr<CallBase> &call)
{
if (call == nullptr) {
TELEPHONY_LOGE("call is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallID() == call->GetCallID()) {
TELEPHONY_LOGE("this call has existed yet!");
return CALL_ERR_PHONE_CALL_ALREADY_EXISTS;
}
}
CallAttributeInfo info;
call->GetCallAttributeInfo(info);
int32_t state;
bool isVoIPCallExists = false;
DelayedSingleton<CallControlManager>::GetInstance()->GetVoIPCallState(state);
if (state == (int32_t)CallStateToApp::CALL_STATE_RINGING) {
isVoIPCallExists = true;
}
if (callObjectPtrList_.size() == NO_CALL_EXIST && (!isVoIPCallExists || info.isEcc)) {
DelayedSingleton<CallConnectAbility>::GetInstance()->ConnectAbility();
}
callObjectPtrList_.emplace_back(call);
if (callObjectPtrList_.size() == ONE_CALL_EXIST) {
DelayedSingleton<CallWiredHeadSet>::GetInstance()->Init();
if (callObjectPtrList_.front()->GetTelCallState() == TelCallState::CALL_STATUS_DIALING) {
isFirstDialCallAdded_ = true;
cv_.notify_all();
}
}
if (FoldStatusManager::IsSmallFoldDevice()) {
DelayedSingleton<FoldStatusManager>::GetInstance()->RegisterFoldableListener();
}
TELEPHONY_LOGI("AddOneCallObject success! callId:%{public}d,call list size:%{public}zu", call->GetCallID(),
callObjectPtrList_.size());
return TELEPHONY_SUCCESS;
}
int32_t CallObjectManager::AddOneVoipCallObject(CallAttributeInfo info)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::map<int32_t, CallAttributeInfo>::iterator it = voipCallObjectList_.find(info.callId);
if (it == voipCallObjectList_.end()) {
voipCallObjectList_[info.callId] = info;
TELEPHONY_LOGI("AddOneVoipCallObject success! callList size:%{public}zu", voipCallObjectList_.size());
return TELEPHONY_SUCCESS;
}
TELEPHONY_LOGI("AddOneVoipCallObject failed!");
return CALL_ERR_PHONE_CALL_ALREADY_EXISTS;
}
int32_t CallObjectManager::DeleteOneVoipCallObject(int32_t callId)
{
std::unique_lock<ffrt::mutex> lock(listMutex_);
std::map<int32_t, CallAttributeInfo>::iterator it = voipCallObjectList_.find(callId);
if (it != voipCallObjectList_.end()) {
voipCallObjectList_.erase(callId);
TELEPHONY_LOGI("DeleteOneVoipCallObject success! callList size:%{public}zu", voipCallObjectList_.size());
}
return TELEPHONY_SUCCESS;
}
bool CallObjectManager::IsVoipCallExist()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
bool res = (voipCallObjectList_.size() != 0);
TELEPHONY_LOGI("has voip call exist:%{public}d", res);
return res;
}
bool CallObjectManager::IsVoipCallExist(TelCallState callState, int32_t &callId)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::map<int32_t, CallAttributeInfo>::iterator it;
for (it = voipCallObjectList_.begin(); it != voipCallObjectList_.end(); ++it) {
if (it->second.callState == callState) {
callId = it->first;
return true;
}
}
TELEPHONY_LOGI("the voip call is does not exist");
return false;
}
void CallObjectManager::ClearVoipList()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
if (voipCallObjectList_.size() != 0) {
voipCallObjectList_.clear();
}
bool res = DelayedSingleton<CallControlManager>::GetInstance()->SetVirtualCall(true);
TELEPHONY_LOGI("SetVirtualCall res: %{public}d.", res);
}
int32_t CallObjectManager::UpdateOneVoipCallObjectByCallId(int32_t callId, TelCallState nextCallState)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::map<int32_t, CallAttributeInfo>::iterator it = voipCallObjectList_.find(callId);
if (it != voipCallObjectList_.end()) {
it->second.callState = nextCallState;
return TELEPHONY_SUCCESS;
}
TELEPHONY_LOGI("UpdateOneVoipCallObjectByCallId failed!");
return TELEPHONY_ERROR;
}
CallAttributeInfo CallObjectManager::GetVoipCallInfo()
{
CallAttributeInfo res;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::map<int32_t, CallAttributeInfo>::iterator it = voipCallObjectList_.begin();
if (it != voipCallObjectList_.end()) {
res = it->second;
return res;
}
return res;
}
CallAttributeInfo CallObjectManager::GetActiveVoipCallInfo()
{
CallAttributeInfo res;
std::map<int32_t, CallAttributeInfo>::iterator it = voipCallObjectList_.begin();
for (; it != voipCallObjectList_.end(); ++it) {
if (it->second.callState == TelCallState::CALL_STATUS_ACTIVE) {
res = it->second;
return res;
}
}
return res;
}
void CallObjectManager::DelayedDisconnectCallConnectAbility(uint64_t time = DISCONNECT_DELAY_TIME)
{
ffrt::submit_h(
[]() {
std::lock_guard<ffrt::mutex> lock(listMutex_);
TELEPHONY_LOGI("delayed disconnect callback begin");
auto controlManager = DelayedSingleton<CallControlManager>::GetInstance();
if (callObjectPtrList_.size() == NO_CALL_EXIST && controlManager->ShouldDisconnectService()) {
auto callConnectAbility = DelayedSingleton<CallConnectAbility>::GetInstance();
callConnectAbility->DisconnectAbility();
TELEPHONY_LOGI("delayed disconnect done");
}
},
{}, {}, ffrt::task_attr().delay(time));
}
int32_t CallObjectManager::DeleteOneCallObject(int32_t callId)
{
TELEPHONY_LOGI("delete one call object, callId:%{public}d", callId);
std::unique_lock<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallID() == callId) {
callObjectPtrList_.erase(it);
TELEPHONY_LOGI("DeleteOneCallObject success! call list size:%{public}zu", callObjectPtrList_.size());
break;
}
}
if (callObjectPtrList_.size() == NO_CALL_EXIST) {
DelayedSingleton<CallWiredHeadSet>::GetInstance()->DeInit();
if (FoldStatusManager::IsSmallFoldDevice()) {
DelayedSingleton<FoldStatusManager>::GetInstance()->UnregisterFoldableListener();
}
if (DelayedSingleton<CallControlManager>::GetInstance()->ShouldDisconnectService()) {
lock.unlock();
DelayedDisconnectCallConnectAbility();
}
}
return TELEPHONY_SUCCESS;
}
void CallObjectManager::DeleteOneCallObject(sptr<CallBase> &call)
{
if (call == nullptr) {
TELEPHONY_LOGE("call is null!");
return;
}
std::unique_lock<ffrt::mutex> lock(listMutex_);
callObjectPtrList_.remove(call);
if (callObjectPtrList_.size() == NO_CALL_EXIST) {
if (FoldStatusManager::IsSmallFoldDevice()) {
DelayedSingleton<FoldStatusManager>::GetInstance()->UnregisterFoldableListener();
}
if (DelayedSingleton<CallControlManager>::GetInstance()->ShouldDisconnectService()) {
lock.unlock();
DelayedDisconnectCallConnectAbility();
}
}
TELEPHONY_LOGI("DeleteOneCallObject success! callList size:%{public}zu", callObjectPtrList_.size());
}
sptr<CallBase> CallObjectManager::GetOneCallObject(int32_t callId)
{
sptr<CallBase> retPtr = nullptr;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = CallObjectManager::callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallID() == callId) {
retPtr = *it;
break;
}
}
return retPtr;
}
sptr<CallBase> CallObjectManager::GetOneCallObject(std::string &phoneNumber)
{
if (phoneNumber.empty()) {
TELEPHONY_LOGE("call is null!");
return nullptr;
}
sptr<CallBase> retPtr = nullptr;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
std::string networkAddress =
DelayedSingleton<CallNumberUtils>::GetInstance()->RemovePostDialPhoneNumber((*it)->GetAccountNumber());
if (networkAddress == phoneNumber) {
TELEPHONY_LOGI("GetOneCallObject success!");
retPtr = *it;
break;
}
}
return retPtr;
}
int32_t CallObjectManager::HasNewCall()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() != CallType::TYPE_VOIP &&
((*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_CREATE ||
(*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_CONNECTING ||
(*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_DIALING ||
(*it)->GetCallType() == CallType::TYPE_SATELLITE)) {
TELEPHONY_LOGE("there is already a new call[callId:%{public}d,state:%{public}d], please redial later",
(*it)->GetCallID(), (*it)->GetCallRunningState());
return CALL_ERR_CALL_COUNTS_EXCEED_LIMIT;
}
}
return TELEPHONY_SUCCESS;
}
int32_t CallObjectManager::IsNewCallAllowedCreate(bool &enabled)
{
enabled = true;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() != CallType::TYPE_VOIP &&
((*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_CREATE ||
(*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_CONNECTING ||
(*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_DIALING ||
(*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_RINGING)) {
TELEPHONY_LOGE("there is already a new call, please redial later");
enabled = false;
return TELEPHONY_ERR_SUCCESS;
}
}
int32_t count = 0;
int32_t callNum = 2;
#ifdef NOT_SUPPORT_MULTICALL
callNum = 1;
#endif
std::list<int32_t> callIdList;
GetCarrierCallList(callIdList);
for (int32_t otherCallId : callIdList) {
sptr<CallBase> call = GetOneCallObject(otherCallId);
if (call != nullptr) {
TelConferenceState confState = call->GetTelConferenceState();
int32_t conferenceId = DelayedSingleton<ImsConference>::GetInstance()->GetMainCall();
if (confState != TelConferenceState::TEL_CONFERENCE_IDLE && conferenceId == otherCallId) {
TELEPHONY_LOGI("there is conference call");
count++;
} else if (confState == TelConferenceState::TEL_CONFERENCE_IDLE) {
count++;
}
}
}
TELEPHONY_LOGI("the count is:%{public}d", count);
if (count >= callNum) {
enabled = false;
}
return TELEPHONY_ERR_SUCCESS;
}
int32_t CallObjectManager::GetCurrentCallNum()
{
int32_t count = 0;
std::list<int32_t> callIdList;
GetCarrierCallList(callIdList);
for (int32_t otherCallId : callIdList) {
sptr<CallBase> call = GetOneCallObject(otherCallId);
if (call != nullptr) {
TelConferenceState confState = call->GetTelConferenceState();
int32_t conferenceId = DelayedSingleton<ImsConference>::GetInstance()->GetMainCall();
if (confState != TelConferenceState::TEL_CONFERENCE_IDLE && conferenceId == otherCallId) {
TELEPHONY_LOGI("there is conference call");
count++;
} else if (confState == TelConferenceState::TEL_CONFERENCE_IDLE) {
count++;
}
}
}
TELEPHONY_LOGI("the count is %{public}d", count);
return count;
}
int32_t CallObjectManager::GetCarrierCallList(std::list<int32_t> &list)
{
list.clear();
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_CS || (*it)->GetCallType() == CallType::TYPE_IMS ||
(*it)->GetCallType() == CallType::TYPE_SATELLITE ||
(*it)->GetCallType() == CallType::TYPE_BLUETOOTH) {
list.emplace_back((*it)->GetCallID());
}
}
return TELEPHONY_SUCCESS;
}
int32_t CallObjectManager::GetVoipCallNum(bool isOnlyIncludeNonVirtualVoIP)
{
int32_t count = 0;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_VOIP &&
(isOnlyIncludeNonVirtualVoIP? (*it)->isNonVirtualCall() : true)) {
count++;
}
}
return count;
}
int32_t CallObjectManager::GetVoipCallList(std::list<int32_t> &list)
{
list.clear();
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_VOIP) {
list.emplace_back((*it)->GetCallID());
}
}
return TELEPHONY_SUCCESS;
}
bool CallObjectManager::HasRingingMaximum()
{
int32_t ringingCount = 0;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_RINGING) {
ringingCount++;
}
}
if (ringingCount >= RINGING_CALL_NUMBER_LEN) {
return true;
}
return false;
}
bool CallObjectManager::HasDialingMaximum()
{
int32_t dialingCount = 0;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_ACTIVE) {
dialingCount++;
}
}
if (dialingCount >= DIALING_CALL_NUMBER_LEN) {
return true;
}
return false;
}
int32_t CallObjectManager::HasEmergencyCall(bool &enabled)
{
enabled = false;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetEmergencyState()) {
enabled = true;
}
}
return TELEPHONY_ERR_SUCCESS;
}
int32_t CallObjectManager::GetNewCallId()
{
int32_t ret = 0;
std::lock_guard<ffrt::mutex> lock(listMutex_);
ret = ++callId_;
return ret;
}
bool CallObjectManager::IsCallExist(int32_t callId)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallID() == callId) {
TELEPHONY_LOGW("the call is exist.");
return true;
}
}
return false;
}
bool CallObjectManager::IsCallExist(std::string &phoneNumber)
{
if (phoneNumber.empty()) {
return false;
}
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
std::string networkAddress =
DelayedSingleton<CallNumberUtils>::GetInstance()->RemovePostDialPhoneNumber((*it)->GetAccountNumber());
if (networkAddress == phoneNumber) {
return true;
}
}
TELEPHONY_LOGI("the call is does not exist.");
return false;
}
bool CallObjectManager::HasCallExist()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
if (callObjectPtrList_.empty()) {
TELEPHONY_LOGI("call list size:%{public}zu", callObjectPtrList_.size());
return false;
}
return true;
}
std::list<sptr<CallBase>> CallObjectManager::GetAllCallList()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
return callObjectPtrList_;
}
bool CallObjectManager::HasCellularCallExist()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_CS || (*it)->GetCallType() == CallType::TYPE_IMS ||
(*it)->GetCallType() == CallType::TYPE_SATELLITE ||
(*it)->GetCallType() == CallType::TYPE_BLUETOOTH) {
if ((*it)->GetTelCallState() != TelCallState::CALL_STATUS_DISCONNECTED &&
(*it)->GetTelCallState() != TelCallState::CALL_STATUS_DISCONNECTING) {
return true;
}
}
}
return false;
}
bool CallObjectManager::HasVoipCallExist()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_VOIP) {
return true;
}
}
return false;
}
bool CallObjectManager::HasOtherBtCallExist(int32_t callId)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallID() == callId) {
continue;
}
if ((*it)->GetCallType() == CallType::TYPE_BLUETOOTH) {
return true;
}
}
return false;
}
bool CallObjectManager::HasIncomingCallCrsType()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_RINGING &&
(*it)->GetCrsType() == CRS_TYPE) {
return true;
}
}
return false;
}
bool CallObjectManager::HasIncomingCallVideoRingType()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() != CallType::TYPE_VOIP &&
(*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_RINGING) {
ContactInfo contactInfo = (*it)->GetCallerInfo();
if (IsVideoRing(contactInfo.personalNotificationRingtone, contactInfo.ringtonePath)) {
return true;
}
}
}
return false;
}
bool CallObjectManager::IsVideoRing(const std::string &personalNotificationRingtone, const std::string &ringtonePath)
{
if ((personalNotificationRingtone.length() > VIDEO_RING_PATH_FIX_TAIL_LENGTH &&
personalNotificationRingtone.substr(personalNotificationRingtone.length() - VIDEO_RING_PATH_FIX_TAIL_LENGTH,
VIDEO_RING_PATH_FIX_TAIL_LENGTH) == VIDEO_RING_PATH_FIX_TAIL) || ringtonePath == SYSTEM_VIDEO_RING) {
TELEPHONY_LOGI("Is video ring.");
return true;
}
return false;
}
bool CallObjectManager::HasVideoCall()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetVideoStateType() == VideoStateType::TYPE_VIDEO && (*it)->GetCallType() != CallType::TYPE_VOIP) {
return true;
}
}
return false;
}
bool CallObjectManager::HasSatelliteCallExist()
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_SATELLITE) {
return true;
}
}
return false;
}
int32_t CallObjectManager::GetSatelliteCallList(std::list<int32_t> &list)
{
list.clear();
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_SATELLITE) {
list.emplace_back((*it)->GetCallID());
}
}
return TELEPHONY_SUCCESS;
}
int32_t CallObjectManager::HasRingingCall(bool &hasRingingCall)
{
hasRingingCall = false;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_RINGING) {
hasRingingCall = true;
break;
}
}
return TELEPHONY_ERR_SUCCESS;
}
int32_t CallObjectManager::HasHoldCall(bool &hasHoldCall)
{
hasHoldCall = false;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_HOLD) {
hasHoldCall = true;
break;
}
}
return TELEPHONY_ERR_SUCCESS;
}
TelCallState CallObjectManager::GetCallState(int32_t callId)
{
TelCallState retState = TelCallState::CALL_STATUS_IDLE;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = CallObjectManager::callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallID() == callId) {
retState = (*it)->GetTelCallState();
break;
}
}
return retState;
}
sptr<CallBase> CallObjectManager::GetOneCallObject(CallRunningState callState)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::reverse_iterator it;
for (it = callObjectPtrList_.rbegin(); it != callObjectPtrList_.rend(); ++it) {
if ((*it)->GetCallRunningState() == callState) {
return (*it);
}
}
return nullptr;
}
sptr<CallBase> CallObjectManager::GetOneCarrierCallObject(CallRunningState callState)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::reverse_iterator it;
for (it = callObjectPtrList_.rbegin(); it!= callObjectPtrList_.rend(); ++it) {
if ((*it)->GetCallRunningState() == callState && (*it)->GetCallType() != CallType::TYPE_VOIP) {
return (*it);
}
}
return nullptr;
}
sptr<CallBase> CallObjectManager::GetOneCallObjectByIndex(int32_t index)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallIndex() == index && (*it)->GetCallType() != CallType::TYPE_VOIP) {
return (*it);
}
}
return nullptr;
}
sptr<CallBase> CallObjectManager::GetOneCallObjectByIndexAndSlotId(int32_t index, int32_t slotId)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallIndex() == index) {
if ((*it)->GetSlotId() == slotId && (*it)->GetCallType() != CallType::TYPE_VOIP) {
return (*it);
}
}
}
return nullptr;
}
sptr<CallBase> CallObjectManager::GetOneCallObjectByIndexSlotIdAndCallType(int32_t index, int32_t slotId,
CallType callType)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
if (callType == CallType::TYPE_BLUETOOTH) {
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_BLUETOOTH && (*it)->GetCallIndex() == index &&
((*it)->GetSlotId() == slotId || (*it)->GetPhoneOrWatchDial() ==
static_cast<int32_t>(PhoneOrWatchDial::WATCH_DIAL))) {
return (*it);
}
}
} else {
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() != CallType::TYPE_BLUETOOTH && (*it)->GetCallIndex() == index &&
(*it)->GetSlotId() == slotId && (*it)->GetCallType() != CallType::TYPE_VOIP) {
return (*it);
}
}
}
return nullptr;
}
sptr<CallBase> CallObjectManager::GetOneCallObjectByVoipCallId(
std::string voipCallId, std::string bundleName, int32_t uid)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_VOIP) {
sptr<VoIPCall> voipCall = reinterpret_cast<VoIPCall *>((*it).GetRefPtr());
if (voipCall->GetVoipCallId() == voipCallId && voipCall->GetVoipBundleName() == bundleName &&
voipCall->GetVoipUid() == uid) {
return (*it);
}
}
}
return nullptr;
}
bool CallObjectManager::IsCallExist(CallType callType, TelCallState callState)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == callType && (*it)->GetTelCallState() == callState) {
return true;
}
}
TELEPHONY_LOGI("the call is does not exist.");
return false;
}
bool CallObjectManager::IsCallExist(TelCallState callState)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetTelCallState() == callState) {
return true;
}
}
TELEPHONY_LOGI("the call is does not exist.");
return false;
}
bool CallObjectManager::IsCallExist(TelCallState callState, int32_t &callId)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetTelCallState() == callState) {
callId = (*it)->GetCallID();
return true;
}
}
TELEPHONY_LOGI("the call is does not exist.");
return false;
}
bool CallObjectManager::IsConferenceCallExist(TelConferenceState state, int32_t &callId)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetTelConferenceState() == state) {
callId = (*it)->GetCallID();
return true;
}
}
TELEPHONY_LOGI("the call is does not exist.");
return false;
}
bool CallObjectManager::HasActivedCallExist(int32_t &callId, bool isIncludeVoipCall)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetTelCallState() == TelCallState::CALL_STATUS_ACTIVE &&
((isIncludeVoipCall && (*it)->isNonVirtualCall()) || (*it)->GetCallType() != CallType::TYPE_VOIP)) {
callId = (*it)->GetCallID();
return true;
}
}
CallAttributeInfo res = GetActiveVoipCallInfo();
if (res.callId >= VOIP_CALL_MINIMUM) {
callId = res.callId;
return true;
}
TELEPHONY_LOGI("the call is does not exist.");
return false;
}
int32_t CallObjectManager::GetCallNum(TelCallState callState, bool isIncludeVoipCall)
{
int32_t num = 0;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetTelCallState() == callState) {
if ((*it)->GetCallType() == CallType::TYPE_VOIP &&
(isIncludeVoipCall ? !(*it)->isNonVirtualCall() : true)) {
continue;
}
++num;
}
}
TELEPHONY_LOGI("callState:%{public}d, num:%{public}d", callState, num);
return num;
}
std::string CallObjectManager::GetCallNumber(TelCallState callState, bool isIncludeVoipCall)
{
std::string number = "";
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetTelCallState() == callState) {
if ((*it)->GetCallType() == CallType::TYPE_VOIP &&
(isIncludeVoipCall ? !(*it)->isNonVirtualCall() : true)) {
continue;
}
number = (*it)->GetAccountNumber();
break;
}
}
return number;
}
std::vector<CallAttributeInfo> CallObjectManager::GetCallInfoList(int32_t slotId, bool isIncludeVoipCall)
{
std::vector<CallAttributeInfo> callVec;
CallAttributeInfo info;
callVec.clear();
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallType() == CallType::TYPE_VOIP &&
(isIncludeVoipCall ? !(*it)->isNonVirtualCall() : true)) {
continue;
}
(void)memset_s(&info, sizeof(CallAttributeInfo), 0, sizeof(CallAttributeInfo));
(*it)->GetCallAttributeInfo(info);
if (info.accountId == slotId && info.callType != CallType::TYPE_OTT) {
callVec.emplace_back(info);
}
}
std::vector<CallAttributeInfo> voipCallVec = GetVoipCallInfoList();
for (CallAttributeInfo voipCall : voipCallVec) {
callVec.emplace_back(voipCall);
}
TELEPHONY_LOGI("call list size is %{public}u", static_cast<uint32_t>(callVec.size()));
return callVec;
}
std::vector<CallAttributeInfo> CallObjectManager::GetVoipCallInfoList()
{
std::vector<CallAttributeInfo> callVec;
int32_t voipState = DelayedSingleton<CallControlManager>::GetInstance()->GetMeetimeCallState();
TELEPHONY_LOGI("voip state is :%{public}d", voipState);
if (voipState == (int32_t)TelCallState::CALL_STATUS_DIALING ||
voipState == (int32_t)TelCallState::CALL_STATUS_INCOMING ||
voipState == (int32_t)TelCallState::CALL_STATUS_IDLE ||
voipState == (int32_t)TelCallState::CALL_STATUS_ALERTING) {
std::map<int32_t, CallAttributeInfo>::iterator it = voipCallObjectList_.begin();
for (; it != voipCallObjectList_.end(); ++it) {
callVec.emplace_back(it->second);
}
}
return callVec;
}
void CallObjectManager::UpdateOneCallObjectByCallId(int32_t callId, TelCallState nextCallState)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin();
for (; it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallID() == callId) {
(*it)->SetTelCallState(nextCallState);
}
}
}
sptr<CallBase> CallObjectManager::GetForegroundCall(bool isIncludeVoipCall)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
sptr<CallBase> liveCall = nullptr;
for (std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if (!isIncludeVoipCall && (*it)->GetCallType() == CallType::TYPE_VOIP) {
continue;
}
TelCallState telCallState = (*it)->GetTelCallState();
if (telCallState == TelCallState::CALL_STATUS_WAITING ||
telCallState == TelCallState::CALL_STATUS_INCOMING) {
liveCall = (*it);
break;
}
if (telCallState == TelCallState::CALL_STATUS_ALERTING ||
telCallState == TelCallState::CALL_STATUS_DIALING) {
liveCall = (*it);
continue;
}
if (telCallState == TelCallState::CALL_STATUS_ACTIVE) {
liveCall = (*it);
continue;
}
if (telCallState == TelCallState::CALL_STATUS_HOLDING) {
liveCall = (*it);
continue;
}
}
return liveCall;
}
sptr<CallBase> CallObjectManager::GetForegroundLiveCall(bool isIncludeVoipCall)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
sptr<CallBase> liveCall = nullptr;
for (std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if (!isIncludeVoipCall && (*it)->GetCallType() == CallType::TYPE_VOIP) {
continue;
}
TelCallState telCallState = (*it)->GetTelCallState();
if (telCallState == TelCallState::CALL_STATUS_ACTIVE) {
liveCall = (*it);
break;
}
if (telCallState == TelCallState::CALL_STATUS_ALERTING ||
telCallState == TelCallState::CALL_STATUS_DIALING) {
liveCall = (*it);
break;
}
}
return liveCall;
}
sptr<CallBase> CallObjectManager::GetIncomingCall(bool isIncludeVoipCall)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
sptr<CallBase> call = nullptr;
for (std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if (!isIncludeVoipCall && (*it)->GetCallType() == CallType::TYPE_VOIP) {
continue;
}
TelCallState callState = (*it)->GetTelCallState();
if (callState == TelCallState::CALL_STATUS_INCOMING || callState == TelCallState::CALL_STATUS_WAITING) {
call = (*it);
break;
}
}
return call;
}
sptr<CallBase> CallObjectManager::GetAudioLiveCall()
{
sptr<CallBase> call = GetForegroundLiveCall(false);
if (call == nullptr) {
call = GetIncomingCall(false);
}
if (call == nullptr) {
call = GetOneCarrierCallObject(CallRunningState::CALL_RUNNING_STATE_HOLD);
}
if (call == nullptr) {
call = GetForegroundLiveCall(true);
}
if (call == nullptr) {
call = GetIncomingCall(true);
}
return call;
}
CellularCallInfo CallObjectManager::GetDialCallInfo()
{
return dialCallInfo_;
}
int32_t CallObjectManager::DealFailDial(sptr<CallBase> call)
{
return ReportCallDisconnected(call);
}
int32_t CallObjectManager::ReportCallDisconnected(sptr<CallBase> call)
{
TELEPHONY_LOGI("ReportCallDisconnected");
if (call == nullptr) {
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
CallDetailInfo callDetatilInfo;
if (memset_s(&callDetatilInfo, sizeof(CallDetailInfo), 0, sizeof(CallDetailInfo)) != EOK) {
TELEPHONY_LOGE("memset_s callDetatilInfo fail");
return TELEPHONY_ERR_MEMSET_FAIL;
}
std::string number = call->GetAccountNumber();
callDetatilInfo.callType = call->GetCallType();
callDetatilInfo.accountId = call->GetSlotId();
callDetatilInfo.index = call->GetCallIndex();
callDetatilInfo.state = TelCallState::CALL_STATUS_DISCONNECTED;
callDetatilInfo.callMode = call->GetVideoStateType();
callDetatilInfo.voiceDomain = static_cast<int32_t>(call->GetCallType());
if (number.length() > kMaxNumberLen) {
TELEPHONY_LOGE("numbser length out of range");
return CALL_ERR_NUMBER_OUT_OF_RANGE;
}
if (memcpy_s(&callDetatilInfo.phoneNum, kMaxNumberLen, number.c_str(), number.length()) != EOK) {
TELEPHONY_LOGE("memcpy_s number failed!");
return TELEPHONY_ERR_MEMCPY_FAIL;
}
return DelayedSingleton<ReportCallInfoHandler>::GetInstance()->UpdateCallReportInfo(callDetatilInfo);
}
std::vector<CallAttributeInfo> CallObjectManager::GetAllCallInfoList(bool isIncludeVoipCall)
{
std::vector<CallAttributeInfo> callVec;
callVec.clear();
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
CallAttributeInfo info;
if ((*it) == nullptr) {
TELEPHONY_LOGE("call is nullptr");
continue;
}
if ((*it)->GetCallType() == CallType::TYPE_VOIP &&
(isIncludeVoipCall ? !(*it)->isNonVirtualCall() : true)) {
continue;
}
(*it)->GetCallAttributeInfo(info);
callVec.emplace_back(info);
}
std::vector<CallAttributeInfo> voipCallVec = GetVoipCallInfoList();
for (CallAttributeInfo voipCall : voipCallVec) {
callVec.emplace_back(voipCall);
}
return callVec;
}
int32_t CallObjectManager::GetCallNumByRunningState(CallRunningState callState)
{
int32_t count = 0;
std::lock_guard<ffrt::mutex> lock(listMutex_);
std::list<sptr<CallBase>>::iterator it;
for (it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
if ((*it)->GetCallRunningState() == callState) {
count++;
continue;
}
}
TELEPHONY_LOGI("callState:%{public}d, count:%{public}d", callState, count);
return count;
}
sptr<CallBase> CallObjectManager::GetForegroundLiveCallByCallId(int32_t callId)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
sptr<CallBase> liveCall = nullptr;
for (std::list<sptr<CallBase>>::iterator it = callObjectPtrList_.begin(); it != callObjectPtrList_.end(); ++it) {
TelCallState telCallState = (*it)->GetTelCallState();
if (telCallState == TelCallState::CALL_STATUS_ACTIVE && (*it)->GetCallID() == callId) {
liveCall = (*it);
break;
}
if ((telCallState == TelCallState::CALL_STATUS_ALERTING ||
telCallState == TelCallState::CALL_STATUS_DIALING) && (*it)->GetCallID() == callId) {
liveCall = (*it);
break;
}
if ((telCallState == TelCallState::CALL_STATUS_WAITING ||
telCallState == TelCallState::CALL_STATUS_INCOMING) && (*it)->GetCallID() == callId) {
liveCall = (*it);
continue;
}
}
return liveCall;
}
bool CallObjectManager::IsNeedSilentInDoNotDisturbMode()
{
sptr<CallBase> foregroundCall = CallObjectManager::GetForegroundCall(false);
if (foregroundCall == nullptr) {
TELEPHONY_LOGE("call object nullptr");
return false;
}
TelCallState telCallState = foregroundCall->GetTelCallState();
if (telCallState == TelCallState::CALL_STATUS_INCOMING) {
int value = foregroundCall->GetParamsByKey("IsNeedSilentInDoNotDisturbMode", 0);
TELEPHONY_LOGI("CallObjectManager::IsNeedSilentInDoNotDisturbMode: %{public}d", value);
if (value == 1) {
return true;
}
}
return false;
}
#ifdef NOT_SUPPORT_MULTICALL
bool CallObjectManager::HasBtCallWithDifferentNumber(const std::string &accountNumber)
{
std::lock_guard<ffrt::mutex> lock(listMutex_);
for (const auto& call : callObjectPtrList_) {
if (call->GetAccountNumber() == accountNumber) {
continue;
}
if (call->GetCallType() == CallType::TYPE_BLUETOOTH) {
return true;
}
}
return false;
}
#endif
}
}