* Copyright (C) 2021-2025 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_status_manager.h"
#include <securec.h>
#include "antifraud_service.h"
#include "call_manager_config.h"
#include "audio_control_manager.h"
#include "bluetooth_call.h"
#include "bluetooth_call_connection.h"
#include "bluetooth_call_service.h"
#include "bool_wrapper.h"
#include "call_ability_report_proxy.h"
#include "call_control_manager.h"
#include "call_earthquake_alarm_locator.h"
#include "call_manager_errors.h"
#include "call_manager_hisysevent.h"
#include "call_number_utils.h"
#include "call_request_event_handler_helper.h"
#include "call_state_processor.h"
#include "call_superprivacy_control_manager.h"
#include "call_voice_assistant_manager.h"
#include "cs_call.h"
#include "core_service_client.h"
#include "datashare_predicates.h"
#ifdef SUPPORT_DSOFTBUS
#include "distributed_communication_manager.h"
#endif
#include "ffrt.h"
#include "hitrace_meter.h"
#include "hitrace/tracechain.h"
#include "ims_call.h"
#include "notification_helper.h"
#include "motion_recognition.h"
#include "os_account_manager.h"
#include "ott_call.h"
#include "parameters.h"
#include "report_call_info_handler.h"
#include "satellite_call.h"
#include "satellite_call_control.h"
#include "screen_sensor_plugin.h"
#include "settings_datashare_helper.h"
#include "sim_state_type.h"
#include "spam_call_adapter.h"
#include "telephony_log_wrapper.h"
#include "uri.h"
#include "voip_call.h"
#include "want_params_wrapper.h"
#ifdef CALL_MANAGER_WATCH_CALL_BLOCKING
#include "watch_lite_call_manager_node.h"
#endif
namespace OHOS {
namespace Telephony {
constexpr int32_t INIT_INDEX = 0;
constexpr int32_t PRESENTATION_RESTRICTED = 3;
constexpr int32_t MAIN_USER_SPACE = 100;
constexpr int32_t PERCENT_SCALE = 100;
const std::string ADVSECMODE_STATE = "ohos.boot.advsecmode.state";
const std::string ANTIFRAUD_FEATURE = "const.telephony.antifraud.supported";
const std::string PRIMARY_CONTACT = "primary_contact";
constexpr const char *SYSTEM_VIDEO_RING = "system_video_ring";
int32_t CallStatusManager::deviceProvisioned_ = DEVICE_PROVISION_UNDEF;
sptr<OOBEStatusObserver> CallStatusManager::oobeStatusObserver_ = nullptr;
CallStatusManager::CallStatusManager()
{
(void)memset_s(&callReportInfo_, sizeof(CallDetailInfo), 0, sizeof(CallDetailInfo));
for (int32_t i = 0; i < SIM_SLOT_COUNT_MD; i++) {
(void)memset_s(&callDetailsInfo_[i], sizeof(CallDetailsInfo), 0, sizeof(CallDetailsInfo));
}
}
CallStatusManager::~CallStatusManager()
{
#ifdef CALL_MANAGER_WATCH_CALL_BLOCKING
DeInitWatchSystemServiceWrapper();
#endif
}
int32_t CallStatusManager::Init()
{
for (int32_t i = 0; i < SIM_SLOT_COUNT_MD; i++) {
callDetailsInfo_[i].callVec.clear();
tmpCallDetailsInfo_[i].callVec.clear();
}
for (int32_t i = 0; i < SIM_SLOT_COUNT_MD; i++) {
priorVideoState_[i] = VideoStateType::TYPE_VOICE;
}
mEventIdTransferMap_.clear();
mOttEventIdTransferMap_.clear();
InitCallBaseEvent();
CallIncomingFilterManagerPtr_ = (std::make_unique<CallIncomingFilterManager>()).release();
#ifdef CALL_MANAGER_WATCH_CALL_BLOCKING
InitWatchSystemServiceWrapper();
#endif
return TELEPHONY_SUCCESS;
}
void CallStatusManager::InitCallBaseEvent()
{
mEventIdTransferMap_[RequestResultEventId::RESULT_DIAL_NO_CARRIER] = CallAbilityEventId::EVENT_DIAL_NO_CARRIER;
mEventIdTransferMap_[RequestResultEventId::RESULT_HOLD_SEND_FAILED] = CallAbilityEventId::EVENT_HOLD_CALL_FAILED;
mEventIdTransferMap_[RequestResultEventId::RESULT_SWAP_SEND_FAILED] = CallAbilityEventId::EVENT_SWAP_CALL_FAILED;
mOttEventIdTransferMap_[OttCallEventId::OTT_CALL_EVENT_FUNCTION_UNSUPPORTED] =
CallAbilityEventId::EVENT_OTT_FUNCTION_UNSUPPORTED;
mEventIdTransferMap_[RequestResultEventId::RESULT_COMBINE_SEND_FAILED] =
CallAbilityEventId::EVENT_COMBINE_CALL_FAILED;
mEventIdTransferMap_[RequestResultEventId::RESULT_SPLIT_SEND_FAILED] =
CallAbilityEventId::EVENT_SPLIT_CALL_FAILED;
}
int32_t CallStatusManager::ReportCallProcedureEvents(const std::string &callId, const std::string &procedureJsonStr)
{
CallManagerHisysevent::ReportCallProcedureEvents(callId, procedureJsonStr);
return TELEPHONY_SUCCESS;
}
int32_t CallStatusManager::HandleCallReportInfo(const CallDetailInfo &info)
{
int32_t ret = TELEPHONY_ERR_FAIL;
callReportInfo_ = info;
if (info.callType == CallType::TYPE_VOIP) {
return HandleVoipCallReportInfo(info);
}
if (info.callType == CallType::TYPE_BLUETOOTH) {
HandleBluetoothCallReportInfo(info);
}
switch (info.state) {
case TelCallState::CALL_STATUS_ACTIVE:
ret = ActiveHandle(info);
break;
case TelCallState::CALL_STATUS_HOLDING:
ret = HoldingHandle(info);
break;
case TelCallState::CALL_STATUS_DIALING: {
ret = DialingHandle(info);
FinishAsyncTrace(HITRACE_TAG_OHOS, "DialCall", getpid());
DelayedSingleton<CallManagerHisysevent>::GetInstance()->JudgingDialTimeOut(
info.accountId, static_cast<int32_t>(info.callType), static_cast<int32_t>(info.callMode));
break;
}
case TelCallState::CALL_STATUS_ALERTING:
ret = AlertHandle(info);
break;
case TelCallState::CALL_STATUS_INCOMING: {
DelayedSingleton<CallControlManager>::GetInstance()->AcquireIncomingLock();
ret = IncomingHandle(info);
DelayedSingleton<CallControlManager>::GetInstance()->ReleaseIncomingLock();
FinishAsyncTrace(HITRACE_TAG_OHOS, "InComingCall", getpid());
DelayedSingleton<CallManagerHisysevent>::GetInstance()->JudgingIncomingTimeOut(
info.accountId, static_cast<int32_t>(info.callType), static_cast<int32_t>(info.callMode));
break;
}
case TelCallState::CALL_STATUS_WAITING:
case TelCallState::CALL_STATUS_DISCONNECTED:
case TelCallState::CALL_STATUS_DISCONNECTING:
ret = HandleCallReportInfoEx(info);
break;
default:
TELEPHONY_LOGE("Invalid call state!");
break;
}
TELEPHONY_LOGI("Entry CallStatusManager HandleCallReportInfo");
HandleDsdaInfo(info.accountId);
DelayedSingleton<BluetoothCallService>::GetInstance()->GetCallState();
TELEPHONY_LOGI("End CallStatusManager HandleCallReportInfo");
return ret;
}
void CallStatusManager::HandleBluetoothCallReportInfo(const CallDetailInfo &info)
{
if (info.state == TelCallState::CALL_STATUS_WAITING || info.state == TelCallState::CALL_STATUS_INCOMING) {
return;
}
sptr<CallBase> call = nullptr;
if (info.index > 0) {
if (info.state == TelCallState::CALL_STATUS_DIALING || info.state == TelCallState::CALL_STATUS_ALERTING) {
call = GetOneCallObjectByIndexSlotIdAndCallType(INIT_INDEX, info.accountId, info.callType);
if (call != nullptr) {
BtCallDialingHandleFirst(call, info);
return;
}
}
if (call == nullptr) {
call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
}
if ((call == nullptr && info.state == TelCallState::CALL_STATUS_DISCONNECTED) || call != nullptr) {
return;
}
} else {
return;
}
if (call == nullptr) {
call = CreateNewCall(info, CallDirection::CALL_DIRECTION_OUT);
if (call == nullptr) {
TELEPHONY_LOGE("Call is NULL");
return;
}
AddOneCallObject(call);
DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
}
return;
}
void CallStatusManager::SetImsDomainInfo(const sptr<CallBase> call, int32_t imsDomain)
{
if (call != nullptr) {
TELEPHONY_LOGI("imsDomain=%{public}d", imsDomain);
call->SetImsDomain(imsDomain);
CallAttributeInfo info;
call->GetCallAttributeInfo(info);
AAFwk::WantParams object = AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(info.extraParamsString);
object.SetParam("imsDomain", AAFwk::Integer::Box(imsDomain));
call->SetExtraParams(object);
}
}
void CallStatusManager::HandleDsdaInfo(int32_t slotId)
{
int32_t dsdsMode = DSDS_MODE_V2;
bool noOtherCall = true;
std::list<int32_t> callIdList;
GetCarrierCallList(callIdList);
int32_t currentCallNum = GetCurrentCallNum();
DelayedSingleton<CallRequestProcess>::GetInstance()->IsExistCallOtherSlot(callIdList, slotId, noOtherCall);
DelayedRefSingleton<CoreServiceClient>::GetInstance().GetDsdsMode(dsdsMode);
TELEPHONY_LOGI("dsdsMode:%{public}d", dsdsMode);
if ((dsdsMode == static_cast<int32_t>(DsdsMode::DSDS_MODE_V5_DSDA) ||
dsdsMode == static_cast<int32_t>(DsdsMode::DSDS_MODE_V5_TDM)) &&
!noOtherCall) {
TELEPHONY_LOGI("Handle DsdaCallInfo");
sptr<CallBase> holdCall = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_HOLD);
if (holdCall != nullptr && currentCallNum > CALL_NUMBER) {
holdCall->SetCanUnHoldState(false);
}
}
}
int32_t CallStatusManager::HandleCallsReportInfo(const CallDetailsInfo &info)
{
bool flag = false;
TELEPHONY_LOGI("call list size:%{public}zu,slotId:%{public}d", info.callVec.size(), info.slotId);
int32_t curSlotId = info.slotId;
if (!DelayedSingleton<CallNumberUtils>::GetInstance()->IsValidSlotId(curSlotId)) {
TELEPHONY_LOGE("invalid slotId!");
return CALL_ERR_INVALID_SLOT_ID;
}
tmpCallDetailsInfo_[curSlotId].callVec.clear();
tmpCallDetailsInfo_[curSlotId] = info;
for (auto &it : info.callVec) {
for (const auto &it1 : callDetailsInfo_[curSlotId].callVec) {
if (it.index == it1.index) {
if (it.state != it1.state || it.mpty != it1.mpty || it.state == TelCallState::CALL_STATUS_ALERTING ||
it.callType == CallType::TYPE_VOIP || it.callMode != it1.callMode || it.callType != it1.callType) {
TELEPHONY_LOGI("handle updated call state:%{public}d", it.state);
HandleCallReportInfo(it);
}
flag = true;
break;
}
}
if (!flag || callDetailsInfo_[curSlotId].callVec.empty()) {
HandleConnectingCallReportInfo(it);
}
flag = false;
}
for (auto &it2 : callDetailsInfo_[curSlotId].callVec) {
for (const auto &it3 : info.callVec) {
if (it2.index == it3.index) {
TELEPHONY_LOGI("state:%{public}d", it2.state);
#ifdef SUPPORT_RTT_CALL
auto controlManager = DelayedSingleton<CallControlManager>::GetInstance();
if (controlManager != nullptr) {
controlManager->RefreshRttManager(it3);
}
#endif
flag = true;
break;
}
}
if (!flag) {
it2.state = TelCallState::CALL_STATUS_DISCONNECTED;
HandleCallReportInfo(it2);
}
flag = false;
}
UpdateCallDetailsInfo(info);
return TELEPHONY_SUCCESS;
}
void CallStatusManager::HandleConnectingCallReportInfo(const CallDetailInfo &info)
{
int32_t callId = ERR_ID;
bool isMeetimeActiveCallExist = CallObjectManager::IsVoipCallExist(TelCallState::CALL_STATUS_ACTIVE, callId);
CallDetailInfo tempInfo = info;
TELEPHONY_LOGI("handle new call state:%{public}d, isMeetimeActiveCallExist:%{public}d",
info.state, isMeetimeActiveCallExist);
if (isMeetimeActiveCallExist && info.state == TelCallState::CALL_STATUS_INCOMING) {
tempInfo.state = TelCallState::CALL_STATUS_WAITING;
}
HandleCallReportInfo(tempInfo);
}
void CallStatusManager::UpdateCallDetailsInfo(const CallDetailsInfo &info)
{
int32_t curSlotId = info.slotId;
callDetailsInfo_[curSlotId].callVec.clear();
callDetailsInfo_[curSlotId] = info;
auto condition = [](CallDetailInfo i) { return i.state == TelCallState::CALL_STATUS_DISCONNECTED; };
auto it_end = std::remove_if(callDetailsInfo_[curSlotId].callVec.begin(),
callDetailsInfo_[curSlotId].callVec.end(), condition);
callDetailsInfo_[curSlotId].callVec.erase(it_end, callDetailsInfo_[curSlotId].callVec.end());
if (callDetailsInfo_[curSlotId].callVec.empty()) {
TELEPHONY_LOGI("clear tmpCallDetailsInfo");
tmpCallDetailsInfo_[curSlotId].callVec.clear();
}
TELEPHONY_LOGI("End CallStatusManager HandleCallsReportInfo slotId:%{public}d, "
"callDetailsInfo_ size:%{public}zu", info.slotId, callDetailsInfo_[curSlotId].callVec.size());
}
int32_t CallStatusManager::HandleVoipCallReportInfo(const CallDetailInfo &info)
{
TELEPHONY_LOGI("Entry CallStatusManager HandleVoipCallReportInfo");
int32_t ret = TELEPHONY_ERR_FAIL;
switch (info.state) {
case TelCallState::CALL_STATUS_ACTIVE:
ret = ActiveVoipCallHandle(info);
break;
case TelCallState::CALL_STATUS_INCOMING: {
ret = IncomingVoipCallHandle(info);
break;
}
case TelCallState::CALL_STATUS_DISCONNECTED:
ret = DisconnectedVoipCallHandle(info);
break;
case TelCallState::CALL_STATUS_DIALING:
ret = OutgoingVoipCallHandle(info);
break;
case TelCallState::CALL_STATUS_ANSWERED:
ret = AnsweredVoipCallHandle(info);
break;
case TelCallState::CALL_STATUS_DISCONNECTING:
ret = DisconnectingVoipCallHandle(info);
break;
default:
TELEPHONY_LOGE("Invalid call state!");
break;
}
CallManagerHisysevent::RecordVoipProcedure(info.voipCallInfo.voipCallId,
VoipProcedureEvent::CALLMANAGER_HANDLE_CALL_STATE_CHANGE, static_cast<int32_t>(info.state));
return ret;
}
int32_t CallStatusManager::HandleDisconnectedCause(const DisconnectedDetails &details)
{
bool ret = DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallDestroyed(details);
if (!ret) {
TELEPHONY_LOGI("NotifyCallDestroyed failed!");
return CALL_ERR_PHONE_CALLSTATE_NOTIFY_FAILED;
}
return TELEPHONY_SUCCESS;
}
int32_t CallStatusManager::HandleEventResultReportInfo(const CellularCallEventInfo &info)
{
if (info.eventType != CellularCallEventType::EVENT_REQUEST_RESULT_TYPE) {
TELEPHONY_LOGE("unexpected type event occurs, eventId:%{public}d", info.eventId);
return CALL_ERR_PHONE_TYPE_UNEXPECTED;
}
TELEPHONY_LOGI("recv one Event, eventId:%{public}d", info.eventId);
sptr<CallBase> call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_DIALING);
if (call != nullptr) {
int32_t ret = DealFailDial(call);
TELEPHONY_LOGI("DealFailDial ret:%{public}d", ret);
}
CallEventInfo eventInfo;
(void)memset_s(&eventInfo, sizeof(CallEventInfo), 0, sizeof(CallEventInfo));
if (mEventIdTransferMap_.find(info.eventId) != mEventIdTransferMap_.end()) {
eventInfo.eventId = mEventIdTransferMap_[info.eventId];
DialParaInfo dialInfo;
if (eventInfo.eventId == CallAbilityEventId::EVENT_DIAL_NO_CARRIER) {
DelayedSingleton<CallControlManager>::GetInstance()->GetDialParaInfo(dialInfo);
if (dialInfo.number.length() > static_cast<size_t>(kMaxNumberLen)) {
TELEPHONY_LOGE("Number out of limit!");
return CALL_ERR_NUMBER_OUT_OF_RANGE;
}
if (memcpy_s(eventInfo.phoneNum, kMaxNumberLen, dialInfo.number.c_str(), dialInfo.number.length()) != EOK) {
TELEPHONY_LOGE("memcpy_s failed!");
return TELEPHONY_ERR_MEMCPY_FAIL;
}
} else if (eventInfo.eventId == CallAbilityEventId::EVENT_COMBINE_CALL_FAILED) {
sptr<CallBase> activeCall = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_ACTIVE);
if (activeCall != nullptr) {
activeCall->HandleCombineConferenceFailEvent();
}
} else if (eventInfo.eventId == CallAbilityEventId::EVENT_HOLD_CALL_FAILED) {
needWaitHold_ = false;
}
DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallEventUpdated(eventInfo);
} else {
TELEPHONY_LOGW("unknown type Event, eventid %{public}d", info.eventId);
}
return TELEPHONY_SUCCESS;
}
int32_t CallStatusManager::HandleOttEventReportInfo(const OttCallEventInfo &info)
{
TELEPHONY_LOGI("recv one Event, eventId:%{public}d", info.ottCallEventId);
CallEventInfo eventInfo;
(void)memset_s(&eventInfo, sizeof(CallEventInfo), 0, sizeof(CallEventInfo));
if (mOttEventIdTransferMap_.find(info.ottCallEventId) != mOttEventIdTransferMap_.end()) {
eventInfo.eventId = mOttEventIdTransferMap_[info.ottCallEventId];
if (strnlen(info.bundleName, kMaxBundleNameLen + 1) > static_cast<size_t>(kMaxBundleNameLen)) {
TELEPHONY_LOGE("Number out of limit!");
return CALL_ERR_NUMBER_OUT_OF_RANGE;
}
if (memcpy_s(eventInfo.bundleName, kMaxBundleNameLen + 1, info.bundleName,
strnlen(info.bundleName, kMaxBundleNameLen + 1)) != EOK) {
TELEPHONY_LOGE("memcpy_s failed!");
return TELEPHONY_ERR_MEMCPY_FAIL;
}
DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallEventUpdated(eventInfo);
} else {
TELEPHONY_LOGW("unknown type Event, eventid %{public}d", info.ottCallEventId);
}
return TELEPHONY_SUCCESS;
}
int32_t CallStatusManager::HandleVoipEventReportInfo(const VoipCallEventInfo &info)
{
TELEPHONY_LOGI("recv one Event, eventId:%{public}d", info.voipCallEvent);
sptr<CallBase> call = GetOneCallObjectByVoipCallId(info.voipCallId, info.bundleName, info.uid);
if (call == nullptr) {
TELEPHONY_LOGE("voip call is null");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
if (call->GetCallRunningState() != CallRunningState::CALL_RUNNING_STATE_ACTIVE
&& call->GetCallRunningState() != CallRunningState::CALL_RUNNING_STATE_DIALING) {
return TELEPHONY_ERR_FAIL;
}
if (info.voipCallEvent == VoipCallEvent::VOIP_CALL_EVENT_MUTED) {
call->SetMicPhoneState(true);
call->SetMicDisabled(false);
} else if (info.voipCallEvent == VoipCallEvent::VOIP_CALL_EVENT_UNMUTED) {
call->SetMicPhoneState(false);
call->SetMicDisabled(false);
} else if (info.voipCallEvent == VoipCallEvent::VOIP_CALL_EVENT_MIC_DISABLE) {
call->SetMicPhoneState(true);
call->SetMicDisabled(true);
}
if (info.voipCallEvent >= VoipCallEvent::VOIP_CALL_EVENT_MUTED &&
info.voipCallEvent <= VoipCallEvent::VOIP_CALL_EVENT_SPEAKER_OFF) {
AudioDevice device = {
.deviceType = AudioDeviceType::DEVICE_EARPIECE,
.address = { 0 },
};
if (DelayedSingleton<AudioProxy>::GetInstance()->GetPreferredOutputAudioDevice(device,
AudioStandard::StreamUsage::STREAM_USAGE_INVALID) == TELEPHONY_SUCCESS) {
DelayedSingleton<AudioDeviceManager>::GetInstance()->SetCurrentAudioDevice(device);
}
}
DelayedSingleton<AudioDeviceManager>::GetInstance()->ReportAudioDeviceInfo(call);
CallManagerHisysevent::RecordVoipProcedure(info.voipCallId,
VoipProcedureEvent::REPORT_AUDIO_EVENT_TO_CALLUI, static_cast<int32_t>(info.voipCallEvent));
return TELEPHONY_SUCCESS;
}
int32_t CallStatusManager::IncomingHandle(const CallDetailInfo &info)
{
TELEPHONY_LOGI("handle incoming state");
int32_t ret = TELEPHONY_SUCCESS;
bool isExisted = false;
ret = PrepareIncomingCall(info, isExisted);
if (isExisted || ret != TELEPHONY_SUCCESS) {
return ret;
}
sptr<CallBase> call = CreateNewCall(info, CallDirection::CALL_DIRECTION_IN);
if (call == nullptr) {
TELEPHONY_LOGE("CreateNewCall failed!");
return CALL_ERR_CALL_OBJECT_IS_NULL;
}
if (IsFromTheSameNumberAtTheSameTime(call)) {
ModifyEsimType();
}
SetContactInfo(call, std::string(info.phoneNum));
auto callNumberUtils = DelayedSingleton<CallNumberUtils>::GetInstance();
if (callNumberUtils != nullptr && call->GetCallType() == CallType::TYPE_BLUETOOTH) {
callNumberUtils->YellowPageAndMarkUpdate(call);
}
#ifdef SUPPORT_DSOFTBUS
auto dcMgrInstance = DelayedSingleton<DistributedCommunicationManager>::GetInstance();
if (!(dcMgrInstance != nullptr && dcMgrInstance->IsSinkRole() && dcMgrInstance->IsConnected())) {
#endif
bool block = false;
if (IsRejectCall(call, info, block)) {
return HandleRejectCall(call, block);
}
PublishIncomingCallBlockInfo(call, block);
#ifdef SUPPORT_DSOFTBUS
}
#endif
if (info.callType != CallType::TYPE_VOIP && info.callType != CallType::TYPE_BLUETOOTH &&
IsRingOnceCall(call, info)) {
return HandleRingOnceCall(call);
}
HandleVideoCallInAdvsecMode(call, info);
AddOneCallObject(call);
StartInComingCallMotionRecognition();
DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
return FinalizeIncomingState(call, info.state);
}
int32_t CallStatusManager::FinalizeIncomingState(sptr<CallBase> &call, const TelCallState nextState)
{
int32_t ret = UpdateCallState(call, nextState);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed!");
return ret;
}
ret = FilterResultsDispose(call);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("FilterResultsDispose failed!");
}
DelayedSingleton<CallControlManager>::GetInstance()->StartFlashRemind();
return ret;
}
int32_t CallStatusManager::PrepareIncomingCall(const CallDetailInfo &info, bool &isExisted)
{
detectStartTime_ = std::chrono::system_clock::from_time_t(0);
int32_t ret = RefreshOldCall(info, isExisted);
if (isExisted) {
return ret;
}
if (info.callType == CallType::TYPE_CS || info.callType == CallType::TYPE_IMS ||
info.callType == CallType::TYPE_SATELLITE) {
ret = IncomingFilterPolicy(info);
}
return ret;
}
void CallStatusManager::HandleVideoCallInAdvsecMode(const sptr<CallBase> &call, const CallDetailInfo &info)
{
if (call->GetVideoStateType() != VideoStateType::TYPE_VIDEO) {
return;
}
if (call->GetCallType() != CallType::TYPE_IMS) {
return;
}
std::string phoneNumber(info.phoneNum);
NumberMarkInfo numberMarkInfo = call->GetNumberMarkInfo();
if (IsTrustedNumber(numberMarkInfo.markType, phoneNumber)) {
return;
}
if (OHOS::system::GetBoolParameter(ADVSECMODE_STATE, false)) {
TELEPHONY_LOGI("is video call in AdvsecMode.");
call->SetForcedReportVoiceCall(true);
}
}
bool CallStatusManager::IsTrustedNumber(MarkType markType, std::string phoneNumber)
{
if (markType == MarkType::MARK_TYPE_YELLOW_PAGE ||
markType == MarkType::MARK_TYPE_ENTERPRISE ||
IsContactPhoneNum(phoneNumber)) {
return true;
}
return false;
}
void CallStatusManager::SetContactInfo(sptr<CallBase> &call, std::string phoneNum)
{
if (call == nullptr) {
TELEPHONY_LOGE("CreateVoipCall failed!");
return;
}
ContactInfo contactInfo = {
.name = "",
.number = phoneNum,
.isContacterExists = false,
.ringtonePath = "",
.isSendToVoicemail = false,
.isEcc = false,
.isVoiceMail = false,
.isQueryComplete = true,
};
if (call->GetCallType() == CallType::TYPE_BLUETOOTH && SetBluetoothCallContactInfo(call, contactInfo, phoneNum)) {
return;
}
ffrt::submit([=, &call]() {
if (call == nullptr) {
TELEPHONY_LOGE("Call is nullptr.");
return;
}
sptr<CallBase> callObjectPtr = call;
ContactInfo contactInfoTemp = contactInfo;
QueryCallerInfo(contactInfoTemp, phoneNum);
if (std::string(contactInfoTemp.ringtonePath).empty() &&
DelayedSingleton<AudioControlManager>::GetInstance()->IsSystemVideoRing(callObjectPtr)) {
if (memcpy_s(
contactInfoTemp.ringtonePath, FILE_PATH_MAX_LEN, SYSTEM_VIDEO_RING, strlen(SYSTEM_VIDEO_RING)) !=
EOK) {
TELEPHONY_LOGE("memcpy_s ringtonePath fail");
};
}
if (DelayedSingleton<AudioControlManager>::GetInstance()->NeedPlayVideoRing(
contactInfoTemp, callObjectPtr) &&
!CallVoiceAssistantManager::GetInstance()->IsStartVoiceBroadcast()) {
AAFwk::WantParams params = callObjectPtr->GetExtraParams();
params.SetParam("VideoRingPath", AAFwk::String::Box(std::string(contactInfoTemp.ringtonePath)));
callObjectPtr->SetExtraParams(params);
}
callObjectPtr->SetCallerInfo(contactInfoTemp);
#ifdef SUPPORT_DSOFTBUS
DelayedSingleton<DistributedCommunicationManager>::GetInstance()->ProcessCallInfo(callObjectPtr,
DistributedDataType::NAME);
#endif
});
}
bool CallStatusManager::SetBluetoothCallContactInfo(sptr<CallBase> &call, ContactInfo &contactInfo,
std::string phoneNum)
{
std::string contactName = DelayedSingleton<BluetoothCallConnection>::GetInstance()->GetHfpContactName(
phoneNum);
if (!contactName.empty()) {
contactInfo.name = contactName;
contactInfo.isContacterExists = true;
call->SetCallerInfo(contactInfo);
AAFwk::WantParams params = call->GetExtraParams();
params.SetParam("BtCallContactName", AAFwk::String::Box(contactName));
call->SetExtraParams(params);
TELEPHONY_LOGI("SetCallerInfo end for type bluetooth.");
return true;
}
return false;
}
int32_t CallStatusManager::HandleRejectCall(sptr<CallBase> &call, bool isBlock)
{
if (call == nullptr) {
TELEPHONY_LOGE("call is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
int32_t ret = call->SetTelCallState(TelCallState::CALL_STATUS_INCOMING);
if (ret != TELEPHONY_SUCCESS && ret != CALL_ERR_NOT_NEW_STATE) {
TELEPHONY_LOGE("Set CallState failed!");
return ret;
}
ret = call->RejectCall();
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("RejectCall failed!");
return ret;
}
if (isBlock) {
PublishIncomingCallBlockInfo(call, isBlock);
return DelayedSingleton<CallControlManager>::GetInstance()->AddBlockLogAndNotification(call);
}
return DelayedSingleton<CallControlManager>::GetInstance()->AddCallLogAndNotification(call);
}
int32_t CallStatusManager::IncomingVoipCallHandle(const CallDetailInfo &info)
{
int32_t ret = TELEPHONY_ERROR;
sptr<CallBase> call = GetOneCallObjectByVoipCallId(
info.voipCallInfo.voipCallId, info.voipCallInfo.voipBundleName, info.voipCallInfo.uid);
if (call != nullptr) {
return TELEPHONY_SUCCESS;
}
call = CreateNewCall(info, CallDirection::CALL_DIRECTION_IN);
if (call == nullptr) {
sptr<VoIPCall> voipCall = reinterpret_cast<VoIPCall *>(call.GetRefPtr());
if (voipCall != nullptr) {
if (voipCall->UpdateCallAttributeInfo(info)) {
return UpdateCallState(call, info.state);
}
}
TELEPHONY_LOGE("CreateVoipCall failed!");
return CALL_ERR_CALL_OBJECT_IS_NULL;
}
call->SetNonVirtualCall(!DelayedSingleton<AudioDeviceManager>::GetInstance()->GetVirtualCall());
call->SetTelCallState(TelCallState::CALL_STATUS_INCOMING);
AddOneCallObject(call);
DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
ret = UpdateCallState(call, info.state);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed!");
return ret;
}
return ret;
}
int32_t CallStatusManager::OutgoingVoipCallHandle(const CallDetailInfo &info)
{
int32_t ret = TELEPHONY_ERROR;
sptr<CallBase> call = GetOneCallObjectByVoipCallId(
info.voipCallInfo.voipCallId, info.voipCallInfo.voipBundleName, info.voipCallInfo.uid);
if (call != nullptr) {
sptr<VoIPCall> voipCall = reinterpret_cast<VoIPCall *>(call.GetRefPtr());
if (voipCall != nullptr) {
voipCall->UpdateCallAttributeInfo(info);
}
return UpdateCallState(call, info.state);
}
call = CreateNewCall(info, CallDirection::CALL_DIRECTION_OUT);
if (call == nullptr) {
TELEPHONY_LOGE("CreateVoipCall failed!");
return CALL_ERR_CALL_OBJECT_IS_NULL;
}
call->SetNonVirtualCall(!DelayedSingleton<AudioDeviceManager>::GetInstance()->GetVirtualCall());
AddOneCallObject(call);
DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
ret = UpdateCallState(call, info.state);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed!");
return ret;
}
return ret;
}
int32_t CallStatusManager::AnsweredVoipCallHandle(const CallDetailInfo &info)
{
int32_t ret = TELEPHONY_ERROR;
sptr<CallBase> call = GetOneCallObjectByVoipCallId(
info.voipCallInfo.voipCallId, info.voipCallInfo.voipBundleName, info.voipCallInfo.uid);
if (call == nullptr) {
return ret;
}
if (CallManagerConfig::ShouldHangUpCellularCallBeforeAnswer(info.voipCallInfo.uid)) {
HangUpCellularCall();
}
if (DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallStateUpdated(
call, TelCallState::CALL_STATUS_INCOMING, TelCallState::CALL_STATUS_ANSWERED)) {
return TELEPHONY_SUCCESS;
} else {
return ret;
}
}
void CallStatusManager::HangUpCellularCall()
{
std::list<int32_t> carrierCallList;
GetCarrierCallList(carrierCallList);
for (int32_t callId : carrierCallList) {
sptr<CallBase> carrierCall = CallObjectManager::GetOneCallObject(callId);
if (carrierCall != nullptr) {
TELEPHONY_LOGI("hang up carrier call id: %{public}d", callId);
carrierCall->HangUpCall();
}
}
}
int32_t CallStatusManager::DisconnectingVoipCallHandle(const CallDetailInfo &info)
{
sptr<CallBase> call = GetOneCallObjectByVoipCallId(
info.voipCallInfo.voipCallId, info.voipCallInfo.voipBundleName, info.voipCallInfo.uid);
if (call == nullptr) {
return TELEPHONY_ERROR;
}
if (GetVoipCallNum(true) == 1) {
bool res = DelayedSingleton<AudioDeviceManager>::GetInstance()->SetVirtualCall(true);
TELEPHONY_LOGE("SetVirtualCall res:%{public}d", res);
}
call->SetNonVirtualCall(false);
return UpdateCallState(call, TelCallState::CALL_STATUS_DISCONNECTING);
}
void CallStatusManager::QueryCallerInfo(ContactInfo &contactInfo, std::string phoneNum)
{
TELEPHONY_LOGI("Entry CallStatusManager QueryCallerInfo");
std::shared_ptr<CallDataBaseHelper> callDataPtr = DelayedSingleton<CallDataBaseHelper>::GetInstance();
if (callDataPtr == nullptr) {
TELEPHONY_LOGE("callDataPtr is nullptr!");
return;
}
DataShare::DataSharePredicates predicates;
predicates.EqualTo(TYPE_ID, 5);
predicates.And();
predicates.EqualTo(IS_DELETED, 0);
predicates.And();
predicates.NotEqualTo(PRIMARY_CONTACT, 1);
predicates.And();
#ifdef TELEPHONY_CUST_SUPPORT
TELEPHONY_LOGI("telephony cust support.");
if (phoneNum.length() >= static_cast<size_t>(QUERY_CONTACT_LEN)) {
TELEPHONY_LOGI("phoneNum is longer than 7");
predicates.BeginWrap();
predicates.EndsWith(DETAIL_INFO, phoneNum.substr(phoneNum.length() - QUERY_CONTACT_LEN));
predicates.Or();
predicates.EndsWith(FORMAT_PHONE_NUMBER, phoneNum.substr(phoneNum.length() - QUERY_CONTACT_LEN));
predicates.EndWrap();
if (!callDataPtr->QueryContactInfoEnhanced(contactInfo, predicates)) {
TELEPHONY_LOGE("Query contact database enhanced fail!");
}
return;
}
#endif
predicates.EqualTo(DETAIL_INFO, phoneNum);
if (!callDataPtr->Query(contactInfo, predicates)) {
TELEPHONY_LOGE("Query contact database fail!");
}
}
int32_t CallStatusManager::IncomingFilterPolicy(const CallDetailInfo &info)
{
if (CallIncomingFilterManagerPtr_ == nullptr) {
TELEPHONY_LOGE("CallIncomingFilterManagerPtr_ is null");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
return CallIncomingFilterManagerPtr_->DoIncomingFilter(info);
}
void CallStatusManager::CallFilterCompleteResult(const CallDetailInfo &info)
{
int32_t ret = TELEPHONY_ERR_FAIL;
sptr<CallBase> call = CreateNewCall(info, CallDirection::CALL_DIRECTION_IN);
if (call == nullptr) {
TELEPHONY_LOGE("CreateNewCall failed!");
return;
}
AddOneCallObject(call);
DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
ret = UpdateCallState(call, info.state);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed!");
return;
}
ret = FilterResultsDispose(call);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("FilterResultsDispose failed!");
return;
}
}
int32_t CallStatusManager::UpdateDialingCallInfo(const CallDetailInfo &info)
{
TELEPHONY_LOGI("UpdateDialingCallInfo start.");
sptr<CallBase> call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
if (call != nullptr) {
TELEPHONY_LOGI("RefreshCallIfNecessary for not null.");
call = RefreshCallIfNecessary(call, info);
return TELEPHONY_SUCCESS;
}
call = GetOneCallObjectByIndex(INIT_INDEX);
if (call == nullptr) {
TELEPHONY_LOGE("call is nullptr");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
std::string oriNum = call->GetAccountNumber();
TELEPHONY_LOGI("RefreshCallIfNecessary");
call = RefreshCallIfNecessary(call, info);
call->SetCallIndex(info.index);
call->SetBundleName(info.bundleName);
call->SetSlotId(info.accountId);
call->SetTelCallState(info.state);
call->SetVideoStateType(info.callMode);
call->SetCallType(info.callType);
call->SetAccountNumber(oriNum);
call->SetImsDomain(info.imsDomain);
ClearPendingState(call);
return TELEPHONY_SUCCESS;
}
int32_t CallStatusManager::DialingHandle(const CallDetailInfo &info)
{
TELEPHONY_LOGI("handle dialing state, index: %{public}d", info.index);
bool isDistributedDeviceDialing = false;
if (info.index > 0) {
if (UpdateDialingHandle(info, isDistributedDeviceDialing)) {
return UpdateDialingCallInfo(info);
}
}
sptr<CallBase> call = CreateNewCall(info, CallDirection::CALL_DIRECTION_OUT);
if (call == nullptr) {
TELEPHONY_LOGE("CreateNewCall failed!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
SetDistributedDeviceDialing(call, isDistributedDeviceDialing);
if (IsDcCallConneceted()) {
SetContactInfo(call, std::string(info.phoneNum));
}
AddOneCallObject(call);
auto callRequestEventHandler = DelayedSingleton<CallRequestEventHandlerHelper>::GetInstance();
if (info.index == INIT_INDEX) {
callRequestEventHandler->SetPendingMo(true, call->GetCallID());
call->SetPhoneOrWatchDial(static_cast<int32_t>(PhoneOrWatchDial::WATCH_DIAL));
SetBtCallDialByPhone(call, false);
StartOutGoingCallMotionRecognition();
}
callRequestEventHandler->RestoreDialingFlag(false);
callRequestEventHandler->RemoveEventHandlerTask();
int32_t ret = call->DialingProcess();
if (ret != TELEPHONY_SUCCESS) {
return ret;
}
DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
MyLocationEngine::StartEccService(call, info);
ret = UpdateCallState(call, TelCallState::CALL_STATUS_DIALING);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
}
return ret;
}
bool CallStatusManager::UpdateDialingHandle(const CallDetailInfo &info, bool &isDistributedDeviceDialing)
{
sptr<CallBase> call = GetOneCallObjectByIndexSlotIdAndCallType(INIT_INDEX, info.accountId, info.callType);
if (info.callType == CallType::TYPE_BLUETOOTH) {
BtCallDialingHandle(call, info);
} else {
if (call == nullptr) {
call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
isDistributedDeviceDialing = IsDistributeCallSourceStatus();
}
}
if (call != nullptr) {
TELEPHONY_LOGI("need update call info");
return true;
}
return false;
}
int32_t CallStatusManager::ActiveHandle(const CallDetailInfo &info)
{
TELEPHONY_LOGI("handle active state");
StopCallMotionRecognition(TelCallState::CALL_STATUS_ACTIVE);
DelayedSingleton<CallControlManager>::GetInstance()->StopFlashRemind();
std::string tmpStr(info.phoneNum);
sptr<CallBase> call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
if (call == nullptr && IsDcCallConneceted()) {
TELEPHONY_LOGW("need create new call.");
CreateAndSaveNewCall(info, CallDirection::CALL_DIRECTION_UNKNOW);
call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
}
if (call == nullptr && !RefreshDialingStateByOtherState(call, info)) {
TELEPHONY_LOGE("Call is NULL");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
ClearPendingState(call);
TELEPHONY_LOGI("refresh call.");
call = RefreshCallIfNecessary(call, info);
SetOriginalCallTypeForActiveState(call);
std::vector<sptr<CallBase>> conferenceCallList = GetConferenceCallList(call->GetSlotId());
if (info.mpty == 1 && conferenceCallList.size() > 1) {
SetConferenceCall(conferenceCallList);
} else {
TELEPHONY_LOGI("SubCallSeparateFromConference %{public}d", call->ExitConference());
}
int32_t ret = UpdateCallState(call, TelCallState::CALL_STATUS_ACTIVE);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
return ret;
}
sptr<CallBase> holdCall = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_HOLD);
if (holdCall != nullptr) {
holdCall->SetCanSwitchCallState(true);
TELEPHONY_LOGI("holdcall:%{public}d can swap", holdCall->GetCallID());
}
#ifdef AUDIO_SUPPORT
ToSpeakerPhone(call);
DelayedSingleton<AudioControlManager>::GetInstance()->SetVolumeAudible();
#endif
TELEPHONY_LOGI("handle active state success");
bool isAntiFraudSupport = OHOS::system::GetBoolParameter(ANTIFRAUD_FEATURE, true);
if (isAntiFraudSupport) {
SetupAntiFraudService(call, info);
}
return ret;
}
int32_t CallStatusManager::GetAntiFraudSlotId()
{
std::lock_guard<ffrt::mutex> lock(mutex_);
return antiFraudSlotId_;
}
int32_t CallStatusManager::GetAntiFraudIndex()
{
std::lock_guard<ffrt::mutex> lock(mutex_);
return antiFraudIndex_;
}
void CallStatusManager::SetAntiFraudSlotId(int32_t slotId)
{
std::lock_guard<ffrt::mutex> lock(mutex_);
antiFraudSlotId_ = slotId;
}
void CallStatusManager::SetAntiFraudIndex(int32_t index)
{
std::lock_guard<ffrt::mutex> lock(mutex_);
antiFraudIndex_ = index;
}
void CallStatusManager::SetupAntiFraudService(const sptr<CallBase> &call, const CallDetailInfo &info)
{
VideoStateType videoStateType = call->GetVideoStateType();
auto antiFraudService = DelayedSingleton<AntiFraudService>::GetInstance();
if (!antiFraudService->IsAntiFraudSwitchOn(videoStateType) ||
!antiFraudService->IsAntiFraudContactsEnabled(videoStateType)) {
return;
}
std::vector<int> activedOsAccountIds;
OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(activedOsAccountIds);
if (activedOsAccountIds.empty() || activedOsAccountIds[0] != MAIN_USER_SPACE) {
TELEPHONY_LOGI("No antifraud detection needed: not in main user space now");
return;
}
std::string tmpStr(info.phoneNum);
NumberMarkInfo numberMarkInfo = call->GetNumberMarkInfo();
int32_t antiFraudState = call->GetAntiFraudState();
if (antiFraudState == static_cast<int32_t>(AntiFraudState::ANTIFRAUD_STATE_RISK) ||
antiFraudState == static_cast<int32_t>(AntiFraudState::ANTIFRAUD_STATE_NOT_RISK_OR_STOPPED) ||
IsContactPhoneNum(tmpStr) ||
numberMarkInfo.markType == MarkType::MARK_TYPE_FRAUD ||
numberMarkInfo.markType == MarkType::MARK_TYPE_YELLOW_PAGE ||
numberMarkInfo.markType == MarkType::MARK_TYPE_ENTERPRISE) {
TELEPHONY_LOGI("No antifraud detection needed: "
"the call was previously identified as fraud, is a contact number, or has a marked type.");
return;
}
StartAntiFraudDetectTask(call, info, tmpStr, videoStateType);
}
void CallStatusManager::StartAntiFraudDetectTask(const sptr<CallBase> &call, const CallDetailInfo &info,
const std::string &phoneNum, const VideoStateType videoStateType)
{
int32_t slotId = call->GetSlotId();
if (slotId == -1 || GetAntiFraudSlotId() != -1 || GetAntiFraudIndex() != -1) {
return;
}
SetAntiFraudSlotId(slotId);
SetAntiFraudIndex(info.index);
wptr<CallBase> callBaseWeakPtr = call;
OHOS::AntiFraudService::AfsDetectType detectType;
CallDirection callDirection = call->GetCallDirection();
detectType.type_ = GetAntiFraudDetectType(slotId, callDirection, videoStateType);
detectType.isFirstTime_ = true;
detectType.callNum_ = info.phoneNum;
detectType.voiceType_ = static_cast<int32_t>(OHOS::AntiFraudService::VoiceType::VOICE_CALL);
ffrt::submit([phoneNum, slotId, info, callBaseWeakPtr, this, detectType]() {
auto antiFraudService = DelayedSingleton<AntiFraudService>::GetInstance();
if (antiFraudService == nullptr) {
return;
}
int32_t ret = antiFraudService->StartAntiFraudService(phoneNum, slotId, info.index, detectType);
sptr<CallBase> callBasePtr = callBaseWeakPtr.promote();
if (callBasePtr == nullptr) {
return;
}
if (ret != 0) {
TELEPHONY_LOGE("StartAntiFraudService failed, stop detect");
StopAntiFraudDetect(callBasePtr, info);
}
});
}
uint32_t CallStatusManager::GetAntiFraudDetectType(
int32_t slotId, const CallDirection callDirection, const VideoStateType videoStateType)
{
sptr<NetworkState> networkState = nullptr;
DelayedRefSingleton<CoreServiceClient>::GetInstance().GetNetworkState(slotId, networkState);
uint32_t type;
if (callDirection == CallDirection::CALL_DIRECTION_OUT ||
(callDirection == CallDirection::CALL_DIRECTION_IN && videoStateType == VideoStateType::TYPE_VIDEO) ||
(networkState != nullptr && networkState->IsRoaming())) {
type = OHOS::AntiFraudService::ANTIFRAUD_DETECT_TYPE_VOICE_SEMANTIC |
OHOS::AntiFraudService::ANTIFRAUD_DETECT_TYPE_SPEECH_SYNTHESIS;
} else {
type = OHOS::AntiFraudService::ANTIFRAUD_DETECT_TYPE_VOICE_SEMANTIC |
OHOS::AntiFraudService::ANTIFRAUD_DETECT_TYPE_SPEECH_SYNTHESIS |
OHOS::AntiFraudService::ANTIFRAUD_DETECT_TYPE_XOIP_TRANSFER;
}
TELEPHONY_LOGI("using antifraud detect type = %{public}u", type);
return type;
}
void CallStatusManager::StopAntiFraudDetect(sptr<CallBase> &call, const CallDetailInfo &info)
{
if (GetAntiFraudSlotId() != call->GetSlotId() || GetAntiFraudIndex() != info.index) {
return;
}
DelayedSingleton<AntiFraudService>::GetInstance()->StopAntiFraudService(call->GetSlotId(), info.index);
SetAntiFraudSlotId(-1);
SetAntiFraudIndex(-1);
TELEPHONY_LOGI("call ending, can begin a new antifraud");
OHOS::AntiFraudService::AntiFraudResultExt antiFraudResultExt;
UpdateAntiFraudState(call, static_cast<int32_t>(AntiFraudState::ANTIFRAUD_STATE_NOT_RISK_OR_STOPPED),
antiFraudResultExt);
}
void CallStatusManager::PauseAntiFraudDetect(sptr<CallBase> &call, const CallDetailInfo &info)
{
if (GetAntiFraudSlotId() != call->GetSlotId() || GetAntiFraudIndex() != info.index) {
return;
}
DelayedSingleton<AntiFraudService>::GetInstance()->StopAntiFraudService(call->GetSlotId(), info.index);
SetAntiFraudSlotId(-1);
SetAntiFraudIndex(-1);
AAFwk::WantParams extraParams = call->GetExtraParams();
int32_t antiFraudState = static_cast<int32_t>(AntiFraudState::ANTIFRAUD_STATE_NOT_RISK_OR_STOPPED);
extraParams.SetParam("antiFraudState", AAFwk::Integer::Box(antiFraudState));
call->SetExtraParams(extraParams);
}
void CallStatusManager::HandleCeliaCall(sptr<CallBase> &call)
{
int32_t slotId = call->GetSlotId();
int32_t index = call->GetCallIndex();
TELEPHONY_LOGI("handle celia call, slotId=%{public}d, index=%{public}d", slotId, index);
if (GetAntiFraudSlotId() != slotId || GetAntiFraudIndex() != index) {
return;
}
DelayedSingleton<AntiFraudService>::GetInstance()->StopAntiFraudService(slotId, index);
SetAntiFraudSlotId(-1);
SetAntiFraudIndex(-1);
TELEPHONY_LOGI("celia call begin, recover AntiFraud SlotId and Index");
OHOS::AntiFraudService::AntiFraudResultExt antiFraudResultExt;
UpdateAntiFraudState(call, static_cast<int32_t>(AntiFraudState::ANTIFRAUD_STATE_NOT_RISK_OR_STOPPED),
antiFraudResultExt);
if (call->GetTelCallState() == TelCallState::CALL_STATUS_ACTIVE) {
int32_t ret = UpdateCallState(call, TelCallState::CALL_STATUS_ACTIVE);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
}
}
}
void CallStatusManager::UpdateAntiFraudState(sptr<CallBase> &call, int32_t antiFraudState,
const OHOS::AntiFraudService::AntiFraudResultExt &antiFraudResultExt)
{
call->SetAntiFraudState(antiFraudState);
AAFwk::WantParams extraParams = call->GetExtraParams();
extraParams.SetParam("antiFraudState", AAFwk::Integer::Box(antiFraudState));
TELEPHONY_LOGI("Report AntiFraudState: %{public}d", antiFraudState);
if (antiFraudState == static_cast<int32_t>(AntiFraudState::ANTIFRAUD_STATE_RISK)) {
extraParams.SetParam("antiFraudResultVoiceText", AAFwk::Integer::Box(
int(antiFraudResultExt.isVoiceSemanticFraud)));
extraParams.SetParam("antiFraudResultVoiceSynthesis", AAFwk::Integer::Box(
int(antiFraudResultExt.isSpeechSynthesisFraud)));
extraParams.SetParam("antiFraudResultXoip", AAFwk::Integer::Box(int(antiFraudResultExt.isXoipFraud)));
int32_t speechSynthesisPercentProb = static_cast<int>(antiFraudResultExt.speechSynthesisProb * PERCENT_SCALE);
extraParams.SetParam("antiFraudProbVoiceSynthesis", AAFwk::Integer::Box(speechSynthesisPercentProb));
TELEPHONY_LOGI("Report antifraud result. Voice Semantic: %{public}d; Speech Synthesis: %{public}d;"
"Xoip: %{public}d. Report Confidence of Voice Synthesis Result: %{public}d",
antiFraudResultExt.isVoiceSemanticFraud, antiFraudResultExt.isSpeechSynthesisFraud,
antiFraudResultExt.isXoipFraud, speechSynthesisPercentProb);
}
call->SetExtraParams(extraParams);
}
bool CallStatusManager::IsContactPhoneNum(const std::string &phoneNum)
{
ContactInfo contactInfo = {
.name = "",
.number = phoneNum,
.isContacterExists = false,
.ringtonePath = "",
.isSendToVoicemail = false,
.isEcc = false,
.isVoiceMail = false,
.isQueryComplete = true,
};
QueryCallerInfo(contactInfo, phoneNum);
if (contactInfo.name.length() < 1) {
TELEPHONY_LOGI("no corresponding contact found");
return false;
} else {
return true;
}
}
void CallStatusManager::TriggerAntiFraud(
int32_t antiFraudState, const OHOS::AntiFraudService::AntiFraudResultExt &antiFraudResultExt)
{
TELEPHONY_LOGI("TriggerAntiState, antiFraudState = %{public}d", antiFraudState);
sptr<CallBase> call = nullptr;
int32_t antiFraudSlotId = GetAntiFraudSlotId();
if (antiFraudSlotId >= SLOT_NUM || antiFraudSlotId < 0) {
return;
}
for (auto &it : callDetailsInfo_[antiFraudSlotId].callVec) {
if (it.index == GetAntiFraudIndex()) {
it.antiFraudState = antiFraudState;
call = GetOneCallObjectByIndexSlotIdAndCallType(it.index, it.accountId, it.callType);
break;
}
}
if (antiFraudState == static_cast<int32_t>(AntiFraudState::ANTIFRAUD_STATE_RISK) ||
antiFraudState == static_cast<int32_t>(AntiFraudState::ANTIFRAUD_STATE_NOT_RISK_OR_STOPPED)) {
SetAntiFraudSlotId(-1);
SetAntiFraudIndex(-1);
TELEPHONY_LOGI("detect finish, can begin a new antifraud");
}
if (call == nullptr) {
return;
}
if (antiFraudState != static_cast<int32_t>(AntiFraudState::ANTIFRAUD_STATE_DEFAULT)) {
UpdateAntiFraudState(call, antiFraudState, antiFraudResultExt);
}
if (call->GetTelCallState() == TelCallState::CALL_STATUS_ACTIVE) {
OHOS::HiviewDFX::HiTraceId chainId = OHOS::HiviewDFX::HiTraceChain::GetId();
AAFwk::WantParams params = call->GetExtraParams();
params.SetParam("traceChainId", AAFwk::String::Box(std::to_string(chainId.GetChainId())));
params.SetParam("traceFlags", AAFwk::String::Box(std::to_string(chainId.GetFlags())));
call->SetExtraParams(params);
int32_t ret = UpdateCallState(call, TelCallState::CALL_STATUS_ACTIVE);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
}
}
}
void CallStatusManager::SetConferenceCall(std::vector<sptr<CallBase>> conferenceCallList)
{
for (auto conferenceCall : conferenceCallList) {
TELEPHONY_LOGI("SetConferenceCall callid : %{public}d; State : %{public}d",
conferenceCall->GetCallID(), conferenceCall->GetTelConferenceState());
conferenceCall->SetTelConferenceState(TelConferenceState::TEL_CONFERENCE_IDLE);
if (conferenceCall->GetTelConferenceState() != TelConferenceState::TEL_CONFERENCE_ACTIVE) {
conferenceCall->LaunchConference();
UpdateCallState(conferenceCall, conferenceCall->GetTelCallState());
}
}
}
int32_t CallStatusManager::ActiveVoipCallHandle(const CallDetailInfo &info)
{
TELEPHONY_LOGI("handle active state");
sptr<CallBase> call = GetOneCallObjectByVoipCallId(
info.voipCallInfo.voipCallId, info.voipCallInfo.voipBundleName, info.voipCallInfo.uid);
if (call == nullptr) {
TELEPHONY_LOGE("voip Call is NULL");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
sptr<VoIPCall> voipCall = reinterpret_cast<VoIPCall *>(call.GetRefPtr());
if (voipCall == nullptr) {
TELEPHONY_LOGE("voip Call is NULL");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
voipCall->UpdateCallAttributeInfo(info);
bool ret = UpdateCallState(call, info.state);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
return ret;
}
TELEPHONY_LOGI("handle active state success");
return ret;
}
int32_t CallStatusManager::HoldingHandle(const CallDetailInfo &info)
{
TELEPHONY_LOGI("handle holding state");
std::string tmpStr(info.phoneNum);
sptr<CallBase> call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
if (call == nullptr && IsDcCallConneceted()) {
CreateAndSaveNewCall(info, CallDirection::CALL_DIRECTION_UNKNOW);
call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
}
if (call == nullptr) {
TELEPHONY_LOGE("Call is NULL");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
PauseAntiFraudDetect(call, info);
TELEPHONY_LOGI("refresh call.");
call = RefreshCallIfNecessary(call, info);
if (info.mpty == 1) {
int32_t ret = call->HoldConference();
if (ret == TELEPHONY_SUCCESS) {
TELEPHONY_LOGI("HoldConference success");
}
}
return UpdateCallStateAndHandleDsdsMode(info, call);
}
int32_t CallStatusManager::WaitingHandle(const CallDetailInfo &info)
{
DelayedSingleton<CallControlManager>::GetInstance()->AcquireIncomingLock();
int32_t ret = IncomingHandle(info);
DelayedSingleton<CallControlManager>::GetInstance()->ReleaseIncomingLock();
return ret;
}
int32_t CallStatusManager::AlertHandle(const CallDetailInfo &info)
{
TELEPHONY_LOGI("handle alerting state");
std::string tmpStr(info.phoneNum);
sptr<CallBase> call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
if (call == nullptr && IsDcCallConneceted()) {
TELEPHONY_LOGI("create new call.");
CreateAndSaveNewCall(info, CallDirection::CALL_DIRECTION_OUT);
call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
}
if (call == nullptr && !RefreshDialingStateByOtherState(call, info)) {
TELEPHONY_LOGE("Call is NULL");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
ClearPendingState(call);
if (call->GetTelCallState() == TelCallState::CALL_STATUS_DISCONNECTING) {
TELEPHONY_LOGE("call is disconnecting.");
return CALL_ERR_CALL_STATE_MISMATCH_OPERATION;
}
TELEPHONY_LOGI("refresh call.");
call = RefreshCallIfNecessary(call, info);
int32_t ret = UpdateCallState(call, TelCallState::CALL_STATUS_ALERTING);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
return ret;
}
#ifdef AUDIO_SUPPORT
ToSpeakerPhone(call);
TurnOffMute(call);
DelayedSingleton<AudioControlManager>::GetInstance()->SetVolumeAudible();
#endif
return ret;
}
int32_t CallStatusManager::DisconnectingHandle(const CallDetailInfo &info)
{
TELEPHONY_LOGI("handle disconnecting state");
std::string tmpStr(info.phoneNum);
sptr<CallBase> call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
if (call == nullptr) {
TELEPHONY_LOGE("Call is NULL");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
StopAntiFraudDetect(call, info);
TELEPHONY_LOGI("refresh call.");
call = RefreshCallIfNecessary(call, info);
SetOriginalCallTypeForDisconnectState(call);
int32_t ret = UpdateCallState(call, TelCallState::CALL_STATUS_DISCONNECTING);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
}
DelayedSingleton<CallControlManager>::GetInstance()->StopFlashRemind();
return ret;
}
int32_t CallStatusManager::DisconnectedVoipCallHandle(const CallDetailInfo &info)
{
TELEPHONY_LOGI("handle disconnected voip call state");
sptr<CallBase> call = GetOneCallObjectByVoipCallId(
info.voipCallInfo.voipCallId, info.voipCallInfo.voipBundleName, info.voipCallInfo.uid);
if (call == nullptr) {
TELEPHONY_LOGE("voip Call is NULL");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
int32_t ret = UpdateCallState(call, TelCallState::CALL_STATUS_DISCONNECTED);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
return ret;
}
if (GetVoipCallNum(true) == 1) {
bool res = DelayedSingleton<AudioDeviceManager>::GetInstance()->SetVirtualCall(true);
TELEPHONY_LOGE("SetVirtualCall res:%{public}d", res);
}
call->SetNonVirtualCall(false);
DeleteOneCallObject(call->GetCallID());
TELEPHONY_LOGI("handle disconnected voip call state success");
return ret;
}
int32_t CallStatusManager::DisconnectedHandle(const CallDetailInfo &info)
{
TELEPHONY_LOGI("handle disconnected state");
if (timeWaitHelper_ != nullptr) {
TELEPHONY_LOGI("ringtone once");
timeWaitHelper_->NotifyAll();
timeWaitHelper_ = nullptr;
}
std::string tmpStr(info.phoneNum);
sptr<CallBase> call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
if (call == nullptr && !RefreshDialingStateByOtherState(call, info)) {
TELEPHONY_LOGE("Call is Null");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
if (call->GetTelCallState() != TelCallState::CALL_STATUS_DISCONNECTING) {
DelayedSingleton<CallControlManager>::GetInstance()->AcquireDisconnectedLock();
}
StopAntiFraudDetect(call, info);
call = RefreshCallIfNecessary(call, info);
RefreshCallDisconnectReason(call, static_cast<int32_t>(info.reason), info.message);
ClearPendingState(call);
SetOriginalCallTypeForDisconnectState(call);
std::vector<std::u16string> callIdList;
call->GetSubCallIdList(callIdList);
CallRunningState previousState = call->GetCallRunningState();
call->ExitConference();
TelCallState priorState = call->GetTelCallState();
UpdateCallState(call, TelCallState::CALL_STATUS_DISCONNECTED);
int32_t callId = call->GetCallID();
MyLocationEngine::StopEccService(callId);
if (needWaitHold_ && GetCallNum(TelCallState::CALL_STATUS_ACTIVE) == 0) {
needWaitHold_ = false;
HandleDialWhenHolding(callId, call);
}
HandleHoldCallOrAutoAnswerCall(call, callIdList, previousState, priorState);
std::vector<sptr<CallBase>> conferenceCallList = GetConferenceCallList(call->GetSlotId());
if (conferenceCallList.size() == 1) {
sptr<CallBase> leftOneConferenceCall = conferenceCallList[0];
if (leftOneConferenceCall != nullptr &&
leftOneConferenceCall->GetTelConferenceState() != TelConferenceState::TEL_CONFERENCE_IDLE) {
TELEPHONY_LOGI("Not enough calls to be a conference!");
leftOneConferenceCall->SetTelConferenceState(TelConferenceState::TEL_CONFERENCE_IDLE);
UpdateCallState(leftOneConferenceCall, leftOneConferenceCall->GetTelCallState());
}
}
auto callControlManager = DelayedSingleton<CallControlManager>::GetInstance();
auto callSuperPrivacyControlManager = DelayedSingleton<CallSuperPrivacyControlManager>::GetInstance();
if (callControlManager == nullptr || callSuperPrivacyControlManager == nullptr) {
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
if (CallObjectManager::GetCurrentCallNum() <= 0) {
callSuperPrivacyControlManager->RestorePrivacyPolicy();
callControlManager->SetReduceRingToneVolume(false);
}
StopCallMotionRecognition(TelCallState::CALL_STATUS_DISCONNECTED);
callControlManager->StopFlashRemind();
return TELEPHONY_SUCCESS;
}
void CallStatusManager::StopCallMotionRecognition(TelCallState nextState)
{
switch (nextState) {
case TelCallState::CALL_STATUS_ACTIVE:
MotionRecogntion::UnsubscribePickupSensor();
MotionRecogntion::UnsubscribeFlipSensor();
break;
case TelCallState::CALL_STATUS_DISCONNECTED:
if (!CallObjectManager::HasCellularCallExist()) {
MotionRecogntion::UnsubscribePickupSensor();
MotionRecogntion::UnsubscribeFlipSensor();
MotionRecogntion::UnsubscribeCloseToEarSensor();
Rosen::UnloadMotionSensor();
}
break;
default:
break;
}
}
std::vector<sptr<CallBase>> CallStatusManager::GetConferenceCallList(int32_t slotId)
{
if (slotId >= SLOT_NUM || slotId < 0) {
return std::vector<sptr<CallBase>>();
}
std::vector<sptr<CallBase>> conferenceCallList;
for (const auto &it : tmpCallDetailsInfo_[slotId].callVec) {
if (it.mpty == 1) {
sptr<CallBase> conferenceCall = GetOneCallObjectByIndexAndSlotId(it.index, it.accountId);
if (conferenceCall != nullptr) {
conferenceCallList.emplace_back(conferenceCall);
}
}
}
TELEPHONY_LOGI("Conference call list size:%{public}zu", conferenceCallList.size());
return conferenceCallList;
}
void CallStatusManager::HandleHoldCallOrAutoAnswerCall(const sptr<CallBase> call,
std::vector<std::u16string> callIdList, CallRunningState previousState, TelCallState priorState)
{
if (call == nullptr) {
TELEPHONY_LOGE("call is null");
return;
}
bool canUnHold = false;
size_t size = callIdList.size();
int32_t activeCallNum = GetCallNum(TelCallState::CALL_STATUS_ACTIVE);
int32_t waitingCallNum = GetCallNum(TelCallState::CALL_STATUS_WAITING);
IsCanUnHold(activeCallNum, waitingCallNum, size, canUnHold);
sptr<CallBase> holdCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_HOLD);
if (previousState != CallRunningState::CALL_RUNNING_STATE_HOLD &&
previousState != CallRunningState::CALL_RUNNING_STATE_ACTIVE &&
priorState == TelCallState::CALL_STATUS_DISCONNECTING) {
if (holdCall != nullptr && canUnHold && holdCall->GetCanUnHoldState()) {
if (holdCall->GetSlotId() == call->GetSlotId()) {
TELEPHONY_LOGI("release call and recover the held call");
holdCall->UnHoldCall();
}
}
}
DeleteOneCallObject(call->GetCallID());
TELEPHONY_LOGI("Ready to uninitialized RttManager when HandleHoldCallOrAutoAnswerCall");
#ifdef NOT_SUPPORT_MULTICALL
AnswerPendingCall();
#else
int32_t dsdsMode = DSDS_MODE_V2;
DelayedRefSingleton<CoreServiceClient>::GetInstance().GetDsdsMode(dsdsMode);
if (dsdsMode == static_cast<int32_t>(DsdsMode::DSDS_MODE_V5_DSDA) ||
dsdsMode == static_cast<int32_t>(DsdsMode::DSDS_MODE_V5_TDM)) {
bool canSwitchCallState = call->GetCanSwitchCallState();
AutoHandleForDsda(canSwitchCallState, priorState, activeCallNum, call->GetSlotId(), true);
return;
}
if (AutoAnswerVideoCallForNotDsda(call, activeCallNum)) {
return;
}
if (dsdsMode == DSDS_MODE_V3) {
AutoAnswer(activeCallNum, waitingCallNum);
}
#endif
}
bool CallStatusManager::AutoAnswerVideoCallForNotDsda(const sptr<CallBase> disconnectedCall, int32_t activeCallNum)
{
std::list<int32_t> callIdList;
GetCarrierCallList(callIdList);
for (int32_t ringCallId : callIdList) {
sptr<CallBase> ringCall = GetOneCallObject(ringCallId);
if (ringCall != nullptr && ringCall->GetAutoAnswerState()) {
int32_t ringVideoState = static_cast<int32_t>(ringCall->GetVideoStateType());
int32_t disconnectedVideoState = static_cast<int32_t>(disconnectedCall->GetVideoStateType());
if (ringVideoState == static_cast<int32_t>(VideoStateType::TYPE_VIDEO) ||
disconnectedVideoState == static_cast<int32_t>(VideoStateType::TYPE_VIDEO) ) {
AutoAnswerForVideoCall(activeCallNum);
return true;
}
}
}
return false;
}
void CallStatusManager::IsCanUnHold(int32_t activeCallNum, int32_t waitingCallNum, int32_t size, bool &canUnHold)
{
int32_t incomingCallNum = GetCallNum(TelCallState::CALL_STATUS_INCOMING);
int32_t answeredCallNum = GetCallNum(TelCallState::CALL_STATUS_ANSWERED);
int32_t dialingCallNum = GetCallNum(TelCallState::CALL_STATUS_ALERTING);
if (answeredCallNum == 0 && incomingCallNum == 0 && (size == 0 || size == 1) && activeCallNum == 0 &&
waitingCallNum == 0 && dialingCallNum == 0) {
canUnHold = true;
}
TELEPHONY_LOGI("CanUnHold state: %{public}d", canUnHold);
}
void CallStatusManager::AutoHandleForDsda(
bool canSwitchCallState, TelCallState priorState, int32_t activeCallNum, int32_t slotId, bool continueAnswer)
{
int32_t dialingCallNum = GetCallNum(TelCallState::CALL_STATUS_DIALING);
int32_t alertingCallNum = GetCallNum(TelCallState::CALL_STATUS_ALERTING);
std::list<int32_t> callIdList;
GetCarrierCallList(callIdList);
for (int32_t ringCallId : callIdList) {
sptr<CallBase> ringCall = GetOneCallObject(ringCallId);
if (ringCall != nullptr && ringCall->GetAutoAnswerState()) {
TELEPHONY_LOGI("ringCall is not nullptr");
int32_t videoState = static_cast<int32_t>(ringCall->GetVideoStateType());
if (videoState == static_cast<int32_t>(VideoStateType::TYPE_VIDEO)) {
TELEPHONY_LOGI("AutoAnswer VideoCall for Dsda");
AutoAnswerForVideoCall(activeCallNum);
AutoUnHoldForDsda(canSwitchCallState, priorState, activeCallNum, slotId);
return;
}
if (dialingCallNum == 0 && alertingCallNum == 0 && activeCallNum == 0 &&
ringCall->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_RINGING) {
TELEPHONY_LOGI("AutoAnswer VoiceCall for Dsda");
AutoAnswerForVoiceCall(ringCall, slotId, continueAnswer);
AutoUnHoldForDsda(canSwitchCallState, priorState, activeCallNum, slotId);
return;
}
}
}
AutoUnHoldForDsda(canSwitchCallState, priorState, activeCallNum, slotId);
}
void CallStatusManager::AutoUnHoldForDsda(
bool canSwitchCallState, TelCallState priorState, int32_t activeCallNum, int32_t slotId)
{
int32_t dialingCallNum = GetCallNum(TelCallState::CALL_STATUS_DIALING);
int32_t waitingCallNum = GetCallNum(TelCallState::CALL_STATUS_WAITING);
int32_t callNum = 2;
std::list<int32_t> callIdList;
GetCarrierCallList(callIdList);
int32_t currentCallNum = GetCurrentCallNum();
for (int32_t otherCallId : callIdList) {
sptr<CallBase> otherCall = GetOneCallObject(otherCallId);
if (otherCall == nullptr) {
TELEPHONY_LOGE("otherCall is nullptr");
continue;
}
TelCallState state = otherCall->GetTelCallState();
TelConferenceState confState = otherCall->GetTelConferenceState();
int32_t conferenceId = ERR_ID;
otherCall->GetMainCallId(conferenceId);
if (slotId != otherCall->GetSlotId() && state == TelCallState::CALL_STATUS_HOLDING &&
otherCall->GetCanUnHoldState() && activeCallNum == 0 && waitingCallNum == 0 &&
dialingCallNum == 0 &&
((confState != TelConferenceState::TEL_CONFERENCE_IDLE && conferenceId == otherCallId) ||
confState == TelConferenceState::TEL_CONFERENCE_IDLE)) {
if (priorState == TelCallState::CALL_STATUS_DISCONNECTING ||
(!canSwitchCallState && currentCallNum == callNum)) {
otherCall->UnHoldCall();
return;
}
}
}
for (int32_t otherCallId : callIdList) {
sptr<CallBase> holdCall = GetOneCallObject(otherCallId);
if (holdCall != nullptr && holdCall->GetTelCallState() == TelCallState::CALL_STATUS_HOLDING) {
if (currentCallNum == callNum) {
holdCall->SetCanUnHoldState(true);
}
}
}
}
void CallStatusManager::AutoAnswerForVoiceCall(sptr<CallBase> ringCall, int32_t slotId, bool continueAnswer)
{
* To prevent repeated AT command delivery.
*/
if (continueAnswer || slotId != ringCall->GetSlotId()) {
DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallStateUpdated(
ringCall, TelCallState::CALL_STATUS_INCOMING, TelCallState::CALL_STATUS_ANSWERED);
int ret = ringCall->AnswerCall(ringCall->GetAnswerVideoState());
if (ret == TELEPHONY_SUCCESS) {
DelayedSingleton<CallControlManager>::GetInstance()->NotifyIncomingCallAnswered(ringCall);
}
TELEPHONY_LOGI("ret = %{public}d", ret);
}
ringCall->SetAutoAnswerState(false);
}
void CallStatusManager::AutoAnswerForVideoCall(int32_t activeCallNum)
{
AutoAnswer(activeCallNum, 0);
}
void CallStatusManager::AutoAnswer(int32_t activeCallNum, int32_t waitingCallNum)
{
int32_t holdingCallNum = GetCallNum(TelCallState::CALL_STATUS_HOLDING);
int32_t dialingCallNum = GetCallNum(TelCallState::CALL_STATUS_DIALING);
int32_t alertingCallNum = GetCallNum(TelCallState::CALL_STATUS_ALERTING);
if (activeCallNum == 0 && waitingCallNum == 0 && holdingCallNum == 0 && dialingCallNum == 0 &&
alertingCallNum == 0) {
std::list<int32_t> ringCallIdList;
GetCarrierCallList(ringCallIdList);
for (int32_t ringingCallId : ringCallIdList) {
sptr<CallBase> ringingCall = GetOneCallObject(ringingCallId);
if (ringingCall == nullptr) {
TELEPHONY_LOGE("ringingCall is nullptr");
return;
}
CallRunningState ringingCallState = ringingCall->GetCallRunningState();
if ((ringingCallState == CallRunningState::CALL_RUNNING_STATE_RINGING &&
(ringingCall->GetAutoAnswerState()))) {
ringingCall->SetAutoAnswerState(false);
int ret = ringingCall->AnswerCall(ringingCall->GetAnswerVideoState());
TELEPHONY_LOGI("ret = %{public}d", ret);
break;
}
}
}
}
int32_t CallStatusManager::UpdateCallState(sptr<CallBase> &call, TelCallState nextState)
{
TELEPHONY_LOGW("UpdateCallState start");
if (call == nullptr) {
TELEPHONY_LOGE("Call is NULL");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
TelCallState priorState = call->GetTelCallState();
VideoStateType videoState = call->GetVideoStateType();
TELEPHONY_LOGI(
"callIndex:%{public}d, callId:%{public}d, priorState:%{public}d, nextState:%{public}d, videoState:%{public}d",
call->GetCallIndex(), call->GetCallID(), priorState, nextState, videoState);
if (call->GetCallType() == CallType::TYPE_SATELLITE) {
DelayedSingleton<SatelliteCallControl>::GetInstance()->
HandleSatelliteCallStateUpdate(call, priorState, nextState);
}
if (priorState == TelCallState::CALL_STATUS_INCOMING && nextState == TelCallState::CALL_STATUS_ACTIVE) {
DelayedSingleton<CallManagerHisysevent>::GetInstance()->JudgingAnswerTimeOut(
call->GetSlotId(), call->GetCallID(), static_cast<int32_t>(call->GetVideoStateType()));
}
int32_t ret = call->SetTelCallState(nextState);
UpdateOneCallObjectByCallId(call->GetCallID(), nextState);
if (ret != TELEPHONY_SUCCESS && ret != CALL_ERR_NOT_NEW_STATE) {
TELEPHONY_LOGE("SetTelCallState failed");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
if (nextState == TelCallState::CALL_STATUS_DISCONNECTED) {
time_t createTime = call->GetCallCreateTime();
AAFwk::WantParams params = call->GetExtraParams();
params.SetParam("createTime", AAFwk::Integer::Box(static_cast<int64_t>(createTime)));
call->SetExtraParams(params);
}
if (!DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallStateUpdated(call, priorState, nextState)) {
TELEPHONY_LOGE(
"NotifyCallStateUpdated failed! priorState:%{public}d,nextState:%{public}d", priorState, nextState);
if (nextState == TelCallState::CALL_STATUS_INCOMING) {
CallManagerHisysevent::WriteIncomingCallFaultEvent(call->GetSlotId(),
static_cast<int32_t>(call->GetCallType()), static_cast<int32_t>(call->GetVideoStateType()), ret,
"NotifyCallStateUpdated failed");
}
return CALL_ERR_PHONE_CALLSTATE_NOTIFY_FAILED;
}
SetVideoCallState(call, nextState);
return TELEPHONY_SUCCESS;
}
void CallStatusManager::SetVideoCallState(sptr<CallBase> &call, TelCallState nextState)
{
if (call == nullptr || call->GetCallType() == CallType::TYPE_VOIP) {
TELEPHONY_LOGE("Call is NULL or calltype is VoIP");
return;
}
int slotId = call->GetSlotId();
if (slotId >= SLOT_NUM || slotId < 0) {
return;
}
auto audioControlManager = DelayedSingleton<AudioControlManager>::GetInstance();
if (audioControlManager == nullptr) {
return;
}
VideoStateType videoState = call->GetVideoStateType();
TELEPHONY_LOGI("nextVideoState:%{public}d, priorVideoState:%{public}d", videoState, priorVideoState_[slotId]);
if (priorVideoState_[slotId] != videoState) {
auto audioControlManager = DelayedSingleton<AudioControlManager>::GetInstance();
if (audioControlManager != nullptr) {
audioControlManager->VideoStateUpdated(call, priorVideoState_[slotId], videoState);
}
auto antiFraudService = DelayedSingleton<AntiFraudService>::GetInstance();
if (antiFraudService != nullptr) {
antiFraudService->UpdateVideoState(priorVideoState_[slotId], videoState);
}
priorVideoState_[slotId] = videoState;
}
if (nextState == TelCallState::CALL_STATUS_DISCONNECTED) {
priorVideoState_[slotId] = VideoStateType::TYPE_VOICE;
}
}
sptr<CallBase> CallStatusManager::RefreshCallIfNecessary(const sptr<CallBase> &call, const CallDetailInfo &info)
{
call->SetNewCallUseBox(info.newCallUseBox);
if (call->GetCallType() == CallType::TYPE_IMS && call->GetVideoStateType() != info.callMode) {
call->SetVideoStateType(info.callMode);
sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(call.GetRefPtr());
imsCall->InitVideoCall();
}
SetImsDomainInfo(call, info.imsDomain);
if (call->GetCallType() == CallType::TYPE_IMS) {
call->SetCrsType(info.crsType);
#ifdef SUPPORT_RTT_CALL
sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(call.GetRefPtr());
imsCall->SetRttState(info.rttState);
imsCall->SetRttChannelId(info.rttChannelId);
#endif
}
if (call->GetCallType() == info.callType) {
TELEPHONY_LOGI("RefreshCallIfNecessary not need Refresh");
return call;
}
return RefreshCall(call, info);
}
sptr<CallBase> CallStatusManager::RefreshCall(const sptr<CallBase> &call, const CallDetailInfo &info)
{
TelCallState priorState = call->GetTelCallState();
CallAttributeInfo attrInfo;
(void)memset_s(&attrInfo, sizeof(CallAttributeInfo), 0, sizeof(CallAttributeInfo));
call->GetCallAttributeBaseInfo(attrInfo);
sptr<CallBase> newCall = CreateNewCall(info, attrInfo.callDirection);
if (newCall == nullptr) {
TELEPHONY_LOGE("RefreshCall createCallFail");
return call;
}
AddOneCallObject(newCall);
newCall->SetCallRunningState(call->GetCallRunningState());
newCall->SetTelConferenceState(call->GetTelConferenceState());
newCall->SetStartTime(attrInfo.startTime);
newCall->SetPolicyFlag(PolicyFlag(call->GetPolicyFlag()));
newCall->SetSpeakerphoneOn(call->IsSpeakerphoneOn());
newCall->SetCallBeginTime(attrInfo.callBeginTime);
newCall->SetCallCreateTime(attrInfo.callCreateTime);
newCall->SetCallEndTime(attrInfo.callEndTime);
newCall->SetRingBeginTime(attrInfo.ringBeginTime);
newCall->SetRingEndTime(attrInfo.ringEndTime);
newCall->SetAnswerType(attrInfo.answerType);
newCall->SetMicPhoneState(call->IsMuted());
DeleteOneCallObject(call->GetCallID());
if (call->GetCallType() == CallType::TYPE_IMS && newCall->GetCallType() == CallType::TYPE_CS && info.mpty == 1) {
sptr<CSCall> csCall = reinterpret_cast<CSCall *>(newCall.GetRefPtr());
csCall->UpdateConferenceId(call->GetCallID());
}
newCall->SetCallId(call->GetCallID());
newCall->SetTelCallState(priorState);
SetImsDomainInfo(newCall, attrInfo.imsDomain);
if (call->GetNumberLocation() != "default") {
newCall->SetNumberLocation(call->GetNumberLocation());
}
NumberMarkInfo numberMarkInfo = call->GetNumberMarkInfo();
if (numberMarkInfo.markType > MarkType::MARK_TYPE_NONE || (attrInfo.isEcc &&
numberMarkInfo.markType > MarkType::MARK_TYPE_DEFAULT && newCall->GetCallType() == CallType::TYPE_CS)) {
newCall->SetNumberMarkInfo(numberMarkInfo);
}
return newCall;
}
void CallStatusManager::SetOriginalCallTypeForActiveState(sptr<CallBase> &call)
{
if (call == nullptr) {
TELEPHONY_LOGE("Call is NULL");
return;
}
TelCallState priorState = call->GetTelCallState();
VideoStateType videoState = call->GetVideoStateType();
int32_t videoStateHistory = call->GetOriginalCallType();
if (priorState == TelCallState::CALL_STATUS_ALERTING || priorState == TelCallState::CALL_STATUS_INCOMING ||
priorState == TelCallState::CALL_STATUS_WAITING) {
if (videoStateHistory != static_cast<int32_t>(videoState)) {
TELEPHONY_LOGD("set videoState:%{public}d as original call type", static_cast<int32_t>(videoState));
call->SetOriginalCallType(static_cast<int32_t>(videoState));
}
} else if (priorState == TelCallState::CALL_STATUS_ACTIVE || priorState == TelCallState::CALL_STATUS_HOLDING) {
int32_t videoStateCurrent =
static_cast<int32_t>(static_cast<uint32_t>(videoStateHistory) | static_cast<uint32_t>(videoState));
TELEPHONY_LOGD("maybe upgrade/downgrade operation, keep video record always, videoStateCurrent:%{public}d",
videoStateCurrent);
call->SetOriginalCallType(videoStateCurrent);
}
}
void CallStatusManager::SetOriginalCallTypeForDisconnectState(sptr<CallBase> &call)
{
if (call == nullptr) {
TELEPHONY_LOGE("Call is NULL");
return;
}
TelCallState priorState = call->GetTelCallState();
CallAttributeInfo attrInfo;
(void)memset_s(&attrInfo, sizeof(CallAttributeInfo), 0, sizeof(CallAttributeInfo));
call->GetCallAttributeBaseInfo(attrInfo);
if (priorState == TelCallState::CALL_STATUS_DIALING || priorState == TelCallState::CALL_STATUS_ALERTING ||
((priorState == TelCallState::CALL_STATUS_INCOMING || priorState == TelCallState::CALL_STATUS_WAITING) &&
attrInfo.answerType != CallAnswerType::CALL_ANSWER_REJECT)) {
TELEPHONY_LOGD("canceled or missed call, set voice type as original call type");
call->SetOriginalCallType(static_cast<int32_t>(VideoStateType::TYPE_VOICE));
}
}
int32_t CallStatusManager::ToSpeakerPhone(sptr<CallBase> &call)
{
int32_t ret = TELEPHONY_ERR_FAIL;
if (call == nullptr) {
TELEPHONY_LOGE("Call is NULL");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
if (call->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_DIALING) {
TELEPHONY_LOGI("Call is CALL_STATUS_DIALING");
return ret;
}
if (call->IsSpeakerphoneOn()) {
AudioDevice device = {
.deviceType = AudioDeviceType::DEVICE_SPEAKER,
.address = { 0 },
};
DelayedSingleton<AudioControlManager>::GetInstance()->SetAudioDevice(device);
ret = call->SetSpeakerphoneOn(false);
}
return ret;
}
int32_t CallStatusManager::TurnOffMute(sptr<CallBase> &call)
{
bool enabled = true;
if (HasEmergencyCall(enabled) != TELEPHONY_SUCCESS) {
TELEPHONY_LOGI("CallStatusManager::TurnOffMute HasEmergencyCall failed.");
}
if (call->GetEmergencyState() || enabled) {
DelayedSingleton<AudioControlManager>::GetInstance()->SetMute(false);
} else {
DelayedSingleton<AudioControlManager>::GetInstance()->SetMute(true);
}
return TELEPHONY_SUCCESS;
}
sptr<CallBase> CallStatusManager::CreateNewCall(const CallDetailInfo &info, CallDirection dir)
{
TELEPHONY_LOGI("CreateNewCall");
DialParaInfo paraInfo;
AppExecFwk::PacMap extras;
extras.Clear();
PackParaInfo(paraInfo, info, dir, extras);
sptr<CallBase> callPtr = CreateNewCallByCallType(paraInfo, info, dir, extras);
if (callPtr == nullptr) {
TELEPHONY_LOGE("CreateNewCall failed!");
return nullptr;
}
DialScene dialScene = (DialScene)extras.GetIntValue("dialScene");
if (dialScene == DialScene::CALL_EMERGENCY) {
callPtr->SetIsEccContact(true);
}
callPtr->SetOriginalCallType(info.originalCallType);
SetCallParams(callPtr, info);
return callPtr;
}
void CallStatusManager::SetCallParams(const sptr<CallBase> &callPtr, const CallDetailInfo &info)
{
AAFwk::WantParams params = callPtr->GetExtraParams();
if (info.callType == CallType::TYPE_VOIP) {
OHOS::HiviewDFX::HiTraceId chainId = OHOS::HiviewDFX::HiTraceChain::GetId();
params.SetParam("traceChainId", AAFwk::String::Box(std::to_string(chainId.GetChainId())));
params.SetParam("traceFlags", AAFwk::String::Box(std::to_string(chainId.GetFlags())));
callPtr->SetExtraParams(params);
return;
}
SimLabel simLabel;
if (DelayedRefSingleton<CoreServiceClient>::GetInstance().GetSimLabel(info.accountId, simLabel) ==
TELEPHONY_ERR_SUCCESS) {
TELEPHONY_LOGI("GetSimLabel success, simType is %{public}d", static_cast<int32_t>(simLabel.simType));
params.SetParam("simType", AAFwk::Integer::Box(static_cast<int32_t>(simLabel.simType)));
params.SetParam("simIndex", AAFwk::Integer::Box(simLabel.index));
callPtr->SetExtraParams(params);
}
if (info.state == TelCallState::CALL_STATUS_INCOMING || info.state == TelCallState::CALL_STATUS_WAITING ||
(info.state == TelCallState::CALL_STATUS_DIALING && (info.index == 0 || IsDcCallConneceted() ||
(info.index > 0 && info.callType == CallType::TYPE_BLUETOOTH)))) {
TELEPHONY_LOGI("NumberLocationUpdate start");
wptr<CallBase> callBaseWeakPtr = callPtr;
ffrt::submit([callBaseWeakPtr, info]() {
sptr<CallBase> callBasePtr = callBaseWeakPtr.promote();
if (callBasePtr == nullptr) {
TELEPHONY_LOGE("callBasePtr is nullptr");
return;
}
DelayedSingleton<CallNumberUtils>::GetInstance()->NumberLocationUpdate(callBasePtr);
#ifdef SUPPORT_DSOFTBUS
DelayedSingleton<DistributedCommunicationManager>::GetInstance()->ProcessCallInfo(callBasePtr,
DistributedDataType::LOCATION);
#endif
if (info.state == TelCallState::CALL_STATUS_DIALING) {
DelayedSingleton<CallNumberUtils>::GetInstance()->YellowPageAndMarkUpdate(callBasePtr);
}
});
}
time_t createTime = std::max(time(nullptr), static_cast<time_t>(0));
callPtr->SetCallCreateTime(createTime);
}
sptr<CallBase> CallStatusManager::CreateNewCallByCallType(
DialParaInfo ¶Info, const CallDetailInfo &info, CallDirection dir, AppExecFwk::PacMap &extras)
{
sptr<CallBase> callPtr = nullptr;
switch (info.callType) {
case CallType::TYPE_CS: {
if (dir == CallDirection::CALL_DIRECTION_OUT) {
callPtr = (std::make_unique<CSCall>(paraInfo, extras)).release();
} else {
callPtr = (std::make_unique<CSCall>(paraInfo)).release();
}
break;
}
case CallType::TYPE_IMS: {
if (dir == CallDirection::CALL_DIRECTION_OUT) {
callPtr = (std::make_unique<IMSCall>(paraInfo, extras)).release();
} else {
callPtr = (std::make_unique<IMSCall>(paraInfo)).release();
}
if (callPtr->GetCallType() == CallType::TYPE_IMS) {
sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
imsCall->InitVideoCall();
#ifdef SUPPORT_RTT_CALL
imsCall->SetRttState(info.rttState);
imsCall->SetRttChannelId(info.rttChannelId);
#endif
}
break;
}
case CallType::TYPE_OTT: {
if (dir == CallDirection::CALL_DIRECTION_OUT) {
callPtr = (std::make_unique<OTTCall>(paraInfo, extras)).release();
} else {
callPtr = (std::make_unique<OTTCall>(paraInfo)).release();
}
break;
}
case CallType::TYPE_VOIP:
case CallType::TYPE_SATELLITE:
case CallType::TYPE_BLUETOOTH: {
callPtr = CreateNewCallByCallTypeEx(paraInfo, info, dir, extras);
break;
}
default:
return nullptr;
}
return callPtr;
}
sptr<CallBase> CallStatusManager::CreateNewCallByCallTypeEx(
DialParaInfo ¶Info, const CallDetailInfo &info, CallDirection dir, AppExecFwk::PacMap &extras)
{
sptr<CallBase> callPtr = nullptr;
switch (info.callType) {
case CallType::TYPE_VOIP: {
callPtr = (std::make_unique<VoIPCall>(paraInfo)).release();
break;
}
case CallType::TYPE_SATELLITE: {
if (dir == CallDirection::CALL_DIRECTION_OUT) {
callPtr = (std::make_unique<SatelliteCall>(paraInfo, extras)).release();
} else {
callPtr = (std::make_unique<SatelliteCall>(paraInfo)).release();
}
break;
}
case CallType::TYPE_BLUETOOTH: {
std::string macAddress = DelayedSingleton<BluetoothCallConnection>::GetInstance()->GetMacAddress();
if (dir == CallDirection::CALL_DIRECTION_OUT) {
callPtr = (std::make_unique<BluetoothCall>(paraInfo, extras, macAddress)).release();
} else {
callPtr = (std::make_unique<BluetoothCall>(paraInfo, macAddress)).release();
}
break;
}
default:
return nullptr;
}
return callPtr;
}
bool CallStatusManager::ShouldRejectIncomingCall(sptr<CallBase> &call)
{
bool hasEcc = false;
if (HasEmergencyCall(hasEcc) == TELEPHONY_SUCCESS && hasEcc) {
CallManagerHisysevent::ReportCallDropChrEvent(call->GetSlotId(), call->GetCallIndex(),
DROP_CALL_BY_EMC_CALL_EXIST);
call->SetApCauseReported(true);
TELEPHONY_LOGI("HasEmergencyCall reject incoming call.");
return true;
}
#ifdef CALL_MANAGER_THERMAL_PROTECTION
if (DelayedSingleton<CallControlManager>::GetInstance()->IsThermalProtectionRequired()) {
TELEPHONY_LOGI("Rejecting call due to thermal protection level");
return true;
}
#endif
#ifdef CONFIG_FACTORY_VERSION
TELEPHONY_LOGI("ShouldRejectIncomingCall: CONFIG_FACTORY_VERSION is true");
return false;
#else
if (CallStatusManager::GetDevProvisioned() != DEVICE_PROVISION_VALID) {
CallManagerHisysevent::ReportCallDropChrEvent(call->GetSlotId(), call->GetCallIndex(),
DROP_CALL_BY_INVALID_DEVICE_PROPERTY);
call->SetApCauseReported(true);
TELEPHONY_LOGW("ShouldRejectIncomingCall: device_provisioned = 0");
return true;
}
auto datashareHelper = SettingsDataShareHelper::GetInstance();
std::string user_setup_complete {"1"};
std::vector<int> activedOsAccountIds;
OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(activedOsAccountIds);
if (activedOsAccountIds.empty()) {
TELEPHONY_LOGW("ShouldRejectIncomingCall: activedOsAccountIds is empty");
return false;
}
int userId = activedOsAccountIds[0];
OHOS::Uri uri_setup(
"datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_"
+ std::to_string(userId) + "?Proxy=true&key=user_setup_complete");
int resp_userSetup = datashareHelper->Query(uri_setup, "user_setup_complete", user_setup_complete);
if (resp_userSetup == TELEPHONY_SUCCESS && (user_setup_complete == "0" || user_setup_complete.empty())) {
CallManagerHisysevent::ReportCallDropChrEvent(call->GetSlotId(), call->GetCallIndex(), DROP_CALL_BY_OOBE);
call->SetApCauseReported(true);
TELEPHONY_LOGW("ShouldRejectIncomingCall: user_setup_complete = 0");
return true;
}
return false;
#endif
}
bool CallStatusManager::ShouldBlockIncomingCall(const sptr<CallBase> &call, const CallDetailInfo &info)
{
bool isEcc = false;
DelayedSingleton<CellularCallConnection>::GetInstance()->IsEmergencyPhoneNumber(
info.phoneNum, info.accountId, isEcc);
if (isEcc) {
TELEPHONY_LOGW("incoming phoneNumber is ecc.");
return false;
}
std::shared_ptr<SpamCallAdapter> spamCallAdapterPtr = std::make_shared<SpamCallAdapter>();
#ifdef CALL_MANAGER_WATCH_CALL_BLOCKING
bool isDetectedSpamCall = spamCallAdapterPtr->DetectSpamCall(
std::string(info.phoneNum), info.accountId, watchTelephonyNode_);
#else
bool isDetectedSpamCall = spamCallAdapterPtr->DetectSpamCall(std::string(info.phoneNum), info.accountId);
#endif
if (!isDetectedSpamCall) {
TELEPHONY_LOGE("DetectSpamCall failed!");
return false;
}
#ifdef CALL_MANAGER_WATCH_CALL_BLOCKING
return HandleWatchCallDisposition(spamCallAdapterPtr, call);
#else
detectStartTime_ = std::chrono::system_clock::now();
if (spamCallAdapterPtr->WaitForDetectResult()) {
TELEPHONY_LOGW("DetectSpamCall no time out");
NumberMarkInfo numberMarkInfo;
bool isBlock = false;
int32_t blockReason;
std::string detectDetails = "";
spamCallAdapterPtr->GetParseResult(isBlock, numberMarkInfo, blockReason, detectDetails);
call->SetNumberMarkInfo(numberMarkInfo);
call->SetBlockReason(blockReason);
call->SetDetectDetails(detectDetails);
AAFwk::WantParams params = call->GetExtraParams();
params.SetParam("blockReason", AAFwk::Integer::Box(blockReason));
call->SetExtraParams(params);
if (isBlock) {
CallManagerHisysevent::ReportCallDropChrEvent(call->GetSlotId(), call->GetCallIndex(),
DROP_CALL_BY_CALL_BLOCKING);
call->SetApCauseReported(true);
return true;
}
}
return false;
#endif
}
#ifdef CALL_MANAGER_WATCH_CALL_BLOCKING
bool CallStatusManager::HandleWatchCallDisposition(std::shared_ptr<SpamCallAdapter> &spamCallAdapterPtr,
const sptr<CallBase> &call)
{
if (spamCallAdapterPtr == nullptr || call == nullptr) {
TELEPHONY_LOGE("invalid param");
return false;
}
CallDisposition disposition = spamCallAdapterPtr->GetCallDisposition();
if (disposition == CallDisposition::INTERCEPTED) {
TELEPHONY_LOGI("reject call");
CallManagerHisysevent::ReportCallDropChrEvent(call->GetSlotId(), call->GetCallIndex(),
DROP_CALL_BY_WATCH_CALL_BLOCKING);
call->SetApCauseReported(true);
return true;
}
if (disposition == CallDisposition::AUTO_ANSWER) {
TELEPHONY_LOGI("antoAnswer call");
AAFwk::WantParams params = call->GetExtraParams();
params.SetParam("isAutoAnswerCall", AAFwk::Boolean::Box(true));
call->SetExtraParams(params);
return false;
}
if (spamCallAdapterPtr->IsRefreshMarkInfo()) {
NumberMarkInfo numberMarkInfo = spamCallAdapterPtr->GetNumberMarkInfo();
call->SetNumberMarkInfo(numberMarkInfo);
TELEPHONY_LOGI("refresh call mark info");
}
return false;
}
#endif
bool CallStatusManager::IsRingOnceCall(const sptr<CallBase> &call, const CallDetailInfo &info)
{
NumberMarkInfo numberMarkInfo = call->GetNumberMarkInfo();
ContactInfo contactInfo = call->GetCallerInfo();
if (numberMarkInfo.markType == MarkType::MARK_TYPE_YELLOW_PAGE || contactInfo.name != "") {
TELEPHONY_LOGW("yellowpage or contact, no need check ring once call");
return false;
}
SimLabel simLabel;
std::string key = "";
DelayedRefSingleton<CoreServiceClient>::GetInstance().GetSimLabel(info.accountId, simLabel);
auto datashareHelper = SettingsDataShareHelper::GetInstance();
std::string is_check_ring_once {"0"};
if (simLabel.simType == SimType::ESIM) {
key = "spamshield_eRule" + std::to_string(info.accountId + 1) + "_phone_switch_ring_once";
} else {
key = "spamshield_sim" + std::to_string(info.accountId + 1) + "_phone_switch_ring_once";
}
OHOS::Uri uri(
"datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=" + key);
int32_t ret = datashareHelper->Query(uri, key, is_check_ring_once);
TELEPHONY_LOGW("is_check_ring_once = %{public}s", is_check_ring_once.c_str());
if (ret != TELEPHONY_SUCCESS || is_check_ring_once == "0") {
return false;
}
auto waitTime = WAIT_TIME_THREE_SECOND;
if (detectStartTime_ != std::chrono::system_clock::from_time_t(0)) {
auto detectEndTime = std::chrono::system_clock::now();
auto diff = detectEndTime - detectStartTime_;
std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(diff);
if (diff >= WAIT_TIME_THREE_SECOND) {
TELEPHONY_LOGW("cost time over 3s, non need check ring once call");
}
waitTime = WAIT_TIME_THREE_SECOND - ms;
}
if (timeWaitHelper_ == nullptr) {
timeWaitHelper_ = std::make_unique<TimeWaitHelper>(waitTime);
}
if (!timeWaitHelper_->WaitForResult()) {
TELEPHONY_LOGW("is not ring once");
timeWaitHelper_ = nullptr;
return false;
}
timeWaitHelper_ = nullptr;
return true;
}
int32_t CallStatusManager::HandleRingOnceCall(sptr<CallBase> &call)
{
if (call == nullptr) {
TELEPHONY_LOGE("call is nullptr!");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
int32_t ret = call->SetTelCallState(TelCallState::CALL_STATUS_INCOMING);
if (ret != TELEPHONY_SUCCESS && ret != CALL_ERR_NOT_NEW_STATE) {
TELEPHONY_LOGE("Set CallState failed!");
return ret;
}
return DelayedSingleton<CallControlManager>::GetInstance()->AddCallLogAndNotification(call);
}
void CallStatusManager::PackParaInfo(
DialParaInfo ¶Info, const CallDetailInfo &info, CallDirection dir, AppExecFwk::PacMap &extras)
{
paraInfo.isEcc = false;
paraInfo.dialType = DialType::DIAL_CARRIER_TYPE;
if (dir == CallDirection::CALL_DIRECTION_OUT && info.callType != CallType::TYPE_VOIP) {
DelayedSingleton<CallControlManager>::GetInstance()->GetDialParaInfo(paraInfo, extras);
}
TELEPHONY_LOGI("is ecc: %{public}d", paraInfo.isEcc);
paraInfo.number = info.phoneNum;
paraInfo.callId = GetNewCallId();
paraInfo.index = info.index;
paraInfo.videoState = info.callMode;
paraInfo.accountId = info.accountId;
paraInfo.callType = info.callType;
paraInfo.callState = info.state;
paraInfo.bundleName = info.bundleName;
paraInfo.crsType = info.crsType;
paraInfo.originalCallType = info.originalCallType;
paraInfo.extraParams =
AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(extras.GetStringValue("extraParams"));
bool value = false;
int32_t namePresentation;
OperatorConfig config;
CoreServiceClient::GetInstance().GetOperatorConfigs(info.accountId, config);
if (config.boolValue.find("support_cnap_bool") != config.boolValue.end()) {
value = config.boolValue["support_cnap_bool"];
}
namePresentation = value ? info.namePresentation : PRESENTATION_RESTRICTED;
paraInfo.extraParams.SetParam("namePresentation", AAFwk::Integer::Box(namePresentation));
paraInfo.extraParams.SetParam("name", AAFwk::String::Box(namePresentation == 0 ? info.name : ""));
paraInfo.phoneOrWatch = info.phoneOrWatch;
paraInfo.newCallUseBox = info.newCallUseBox;
}
bool CallStatusManager::IsFocusModeOpen()
{
auto datashareHelper = SettingsDataShareHelper::GetInstance();
std::string focusModeEnable {"0"};
std::vector<int> activedOsAccountIds;
OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(activedOsAccountIds);
if (activedOsAccountIds.empty()) {
TELEPHONY_LOGW("ShouldRejectIncomingCall: activedOsAccountIds is empty");
return false;
}
int userId = activedOsAccountIds[0];
OHOS::Uri uri(
"datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_"
+ std::to_string(userId) + "?Proxy=true&key=focus_mode_enable");
int resp = datashareHelper->Query(uri, "focus_mode_enable", focusModeEnable);
TELEPHONY_LOGI("IsFocusModeOpen: userId = %{public}d, focus_mode_enable = %{public}s",
userId, focusModeEnable.c_str());
if (resp == TELEPHONY_SUCCESS && focusModeEnable == "1") {
return true;
}
return false;
}
bool CallStatusManager::IsRejectCall(sptr<CallBase> &call, const CallDetailInfo &info, bool &block)
{
int32_t state;
DelayedSingleton<CallControlManager>::GetInstance()->GetVoIPCallState(state);
if (ShouldRejectIncomingCall(call) || state == static_cast<int32_t>(CallStateToApp::CALL_STATE_RINGING)) {
CallManagerHisysevent::HiWriteBehaviorEventPhoneUE(
CALL_INCOMING_REJECT_BY_SYSTEM, PNAMEID_KEY, KEY_CALL_MANAGER, PVERSIONID_KEY, "",
ACTION_TYPE, REJECT_BY_OOBE);
block = false;
return true;
}
if (info.callType != CallType::TYPE_VOIP && info.callType != CallType::TYPE_BLUETOOTH &&
ShouldBlockIncomingCall(call, info)) {
CallManagerHisysevent::HiWriteBehaviorEventPhoneUE(
CALL_INCOMING_REJECT_BY_SYSTEM, PNAMEID_KEY, KEY_CALL_MANAGER, PVERSIONID_KEY, "",
ACTION_TYPE, REJECT_BY_NUM_BLOCK);
block = true;
return true;
}
if (IsFocusModeOpen()) {
int ret = Notification::NotificationHelper::IsNeedSilentInDoNotDisturbMode(info.phoneNum, 0);
TELEPHONY_LOGI("IsNeedSilentInDoNotDisturbMode ret:%{public}d", ret);
if (ret == 0) {
CallManagerHisysevent::ReportCallDropChrEvent(call->GetSlotId(), call->GetCallIndex(),
DROP_CALL_BY_FOCUS_MODE);
call->SetApCauseReported(true);
CallManagerHisysevent::HiWriteBehaviorEventPhoneUE(
CALL_INCOMING_REJECT_BY_SYSTEM, PNAMEID_KEY, KEY_CALL_MANAGER, PVERSIONID_KEY, "",
ACTION_TYPE, REJECT_IN_FOCUSMODE);
AAFwk::WantParams params = call->GetExtraParams();
params.SetParam("IsNeedSilentInDoNotDisturbMode", AAFwk::Integer::Box(1));
call->SetExtraParams(params);
}
}
return false;
}
bool CallStatusManager::PublishIncomingCallBlockInfo(const sptr<CallBase> &callObjectPtr, bool block)
{
AAFwk::Want want;
want.SetParam("callId", callObjectPtr->GetCallID());
want.SetParam("isBlocked", block);
want.SetAction("event.custom.callStatus.INCOMINGCALL_BLOCK_INFO");
EventFwk::CommonEventData data;
data.SetWant(want);
EventFwk::CommonEventPublishInfo publishInfo;
publishInfo.SetOrdered(false);
std::vector<std::string> callPermissions;
callPermissions.emplace_back(Permission::GET_TELEPHONY_STATE);
publishInfo.SetSubscriberPermissions(callPermissions);
bool result = EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo, nullptr);
TELEPHONY_LOGI("publish incoming call block info result : %{public}d", result);
return result;
}
void CallStatusManager::CreateAndSaveNewCall(const CallDetailInfo &info, CallDirection direction)
{
if (GetOneCallObjectByIndex(INIT_INDEX) != nullptr) {
TELEPHONY_LOGI("get init_index call success");
UpdateDialingCallInfo(info);
return;
}
auto call = CreateNewCall(info, direction);
if (call != nullptr) {
ffrt::submit([=]() {
DelayedSingleton<CallNumberUtils>::GetInstance()->YellowPageAndMarkUpdate(call);
});
AddOneCallObject(call);
DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
}
}
int32_t CallStatusManager::UpdateCallStateAndHandleDsdsMode(const CallDetailInfo &info, sptr<CallBase> &call)
{
if (call == nullptr) {
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
TelCallState priorState = call->GetTelCallState();
int32_t ret = UpdateCallState(call, TelCallState::CALL_STATUS_HOLDING);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
}
int32_t callId = call->GetCallID();
int32_t dsdsMode = DSDS_MODE_V2;
DelayedRefSingleton<CoreServiceClient>::GetInstance().GetDsdsMode(dsdsMode);
TELEPHONY_LOGE("HoldingHandle dsdsMode:%{public}d", dsdsMode);
bool canSwitchCallState = call->GetCanSwitchCallState();
if (dsdsMode == static_cast<int32_t>(DsdsMode::DSDS_MODE_V5_DSDA) ||
dsdsMode == static_cast<int32_t>(DsdsMode::DSDS_MODE_V5_TDM)) {
int32_t activeCallNum = GetCallNum(TelCallState::CALL_STATUS_ACTIVE);
if (needWaitHold_ && activeCallNum == 0) {
needWaitHold_ = false;
HandleDialWhenHolding(callId, call);
} else {
TelConferenceState confState = call->GetTelConferenceState();
int32_t conferenceId = ERR_ID;
call->GetMainCallId(conferenceId);
if (confState != TelConferenceState::TEL_CONFERENCE_IDLE && conferenceId == callId) {
AutoHandleForDsda(canSwitchCallState, priorState, activeCallNum, call->GetSlotId(), false);
} else if (confState == TelConferenceState::TEL_CONFERENCE_IDLE) {
AutoHandleForDsda(canSwitchCallState, priorState, activeCallNum, call->GetSlotId(), false);
}
}
}
return ret;
}
void CallStatusManager::HandleDialWhenHolding(int32_t callId, sptr<CallBase> &call)
{
auto callRequestEventHandler = DelayedSingleton<CallRequestEventHandlerHelper>::GetInstance();
if (callRequestEventHandler->IsPendingHangup()) {
sptr<CallBase> holdCall = CallObjectManager::GetOneCallObject(callId);
if (holdCall != nullptr) {
holdCall->UnHoldCall();
}
int32_t pendingHangupCallId = callRequestEventHandler->GetPendingHangupCallId();
sptr<CallBase> pendingHangupCall = CallObjectManager::GetOneCallObject(pendingHangupCallId);
if (pendingHangupCall != nullptr) {
UpdateCallState(pendingHangupCall, TelCallState::CALL_STATUS_DISCONNECTED);
DeleteOneCallObject(pendingHangupCallId);
}
callRequestEventHandler->SetPendingHangup(false, -1);
auto callControlManager = DelayedSingleton<CallControlManager>::GetInstance();
if (callControlManager != nullptr) {
callControlManager->RemovePendingHangupProtectTask();
}
} else {
int32_t result = DelayedSingleton<CellularCallConnection>::GetInstance()->Dial(GetDialCallInfo());
sptr<CallBase> dialCall = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_DIALING);
if (result != TELEPHONY_SUCCESS && dialCall != nullptr) {
DealFailDial(call);
TELEPHONY_LOGI("Dial call fail");
}
}
}
bool CallStatusManager::IsDcCallConneceted()
{
std::string dcStatus = "";
auto settingHelper = SettingsDataShareHelper::GetInstance();
if (settingHelper != nullptr) {
OHOS::Uri settingUri(SettingsDataShareHelper::SETTINGS_DATASHARE_URI);
settingHelper->Query(settingUri, "distributed_modem_state", dcStatus);
}
if (dcStatus == "1_sink" || dcStatus == "1_source") {
return true;
}
return false;
}
bool CallStatusManager::IsDistributeCallSourceStatus()
{
std::string dcStatus = "";
auto settingHelper = SettingsDataShareHelper::GetInstance();
if (settingHelper != nullptr) {
OHOS::Uri settingUri(SettingsDataShareHelper::SETTINGS_DATASHARE_URI);
settingHelper->Query(settingUri, "distributed_modem_state", dcStatus);
}
if (dcStatus == "1_source") {
return true;
}
return false;
}
void CallStatusManager::SetBtCallDialByPhone(const sptr<CallBase> &call, bool isBtCallDialByPhone)
{
if (call == nullptr) {
return;
}
CallAttributeInfo info;
call->GetCallAttributeInfo(info);
AAFwk::WantParams object = AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(info.extraParamsString);
object.SetParam("isBtCallDialByPhone", AAFwk::Boolean::Box(isBtCallDialByPhone));
call->SetExtraParams(object);
call->GetCallAttributeBaseInfo(info);
}
void CallStatusManager::BtCallDialingHandle(sptr<CallBase> &call, const CallDetailInfo &info)
{
if (call != nullptr) {
call->SetPhoneOrWatchDial(static_cast<int32_t>(PhoneOrWatchDial::WATCH_DIAL));
SetBtCallDialByPhone(call, false);
} else {
call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
if (call != nullptr) {
call->SetPhoneOrWatchDial(static_cast<int32_t>(PhoneOrWatchDial::PHONE_DIAL));
SetBtCallDialByPhone(call, true);
}
}
}
void CallStatusManager::SetDistributedDeviceDialing(sptr<CallBase> call, bool isDistributedDeviceDialing)
{
if (call == nullptr) {
return;
}
if (isDistributedDeviceDialing) {
AAFwk::WantParams extraParams;
extraParams.SetParam("isDistributedDeviceDialing", AAFwk::String::Box("true"));
call->SetExtraParams(extraParams);
}
}
void CallStatusManager::BtCallDialingHandleFirst(sptr<CallBase> call, const CallDetailInfo &info)
{
if (call == nullptr) {
return;
}
call->SetPhoneOrWatchDial(static_cast<int32_t>(PhoneOrWatchDial::WATCH_DIAL));
SetBtCallDialByPhone(call, false);
if (info.state == TelCallState::CALL_STATUS_ALERTING) {
UpdateDialingCallInfo(info);
if (call->GetTelCallState() == TelCallState::CALL_STATUS_ALERTING) {
call->SetTelCallState(TelCallState::CALL_STATUS_DIALING);
}
}
}
int32_t CallStatusManager::HandleCallReportInfoEx(const CallDetailInfo &info)
{
int32_t ret = TELEPHONY_ERR_FAIL;
switch (info.state) {
case TelCallState::CALL_STATUS_WAITING:
ret = WaitingHandle(info);
break;
case TelCallState::CALL_STATUS_DISCONNECTED:
ret = DisconnectedHandle(info);
break;
case TelCallState::CALL_STATUS_DISCONNECTING:
ret = DisconnectingHandle(info);
break;
default:
TELEPHONY_LOGE("Invalid call state!");
break;
}
return ret;
}
void CallStatusManager::ClearPendingState(sptr<CallBase> &call)
{
auto callRequestEventHandler = DelayedSingleton<CallRequestEventHandlerHelper>::GetInstance();
int32_t callId = call->GetCallID();
TELEPHONY_LOGI("check clear pending state callId = %{public}d", callId);
if (callRequestEventHandler->HasPendingMo(callId)) {
callRequestEventHandler->SetPendingMo(false, -1);
}
if (callRequestEventHandler->HasPendingHangup(callId)) {
if (call->GetCallRunningState() != CallRunningState::CALL_RUNNING_STATE_ENDED) {
call->HangUpCall();
}
callRequestEventHandler->SetPendingHangup(false, -1);
auto callControlManager = DelayedSingleton<CallControlManager>::GetInstance();
if (callControlManager != nullptr) {
callControlManager->RemovePendingHangupProtectTask();
}
}
}
void CallStatusManager::RefreshCallDisconnectReason(const sptr<CallBase> &call, int32_t reason,
const std::string &message)
{
switch (reason) {
case static_cast<int32_t>(RilDisconnectedReason::DISCONNECTED_REASON_CS_CALL_ANSWERED_ELSEWHER):
if (call->GetCallType() == CallType::TYPE_CS) {
call->SetAnswerType(CallAnswerType::CALL_ANSWERED_ELSEWHER);
TELEPHONY_LOGI("cs call answered elsewhere");
}
break;
case static_cast<int32_t>(RilDisconnectedReason::DISCONNECTED_REASON_ANSWERED_ELSEWHER):
{
TELEPHONY_LOGI("RefreshCallDisconnectReason message[%{public}s]", message.c_str());
std::string lowerStr = message;
std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(), ::tolower);
bool isSinkRole = false;
#ifdef SUPPORT_DSOFTBUS
isSinkRole = DelayedSingleton<DistributedCommunicationManager>::GetInstance()->IsSinkRole();
#endif
if (isSinkRole || lowerStr.find("elsewhere") != std::string::npos) {
call->SetAnswerType(CallAnswerType::CALL_ANSWERED_ELSEWHER);
TELEPHONY_LOGI("call answered elsewhere");
}
}
break;
case static_cast<int32_t>(RilDisconnectedReason::DISCONNECTED_REASON_NORMAL):
{
AAFwk::WantParams params = call->GetExtraParams();
params.SetParam("disconnectedReason",
AAFwk::Integer::Box(static_cast<int32_t>(CallAnswerType::CALL_DISCONNECTED_BY_REMOTE)));
call->SetExtraParams(params);
}
break;
default:
break;
}
}
#ifdef NOT_SUPPORT_MULTICALL
void CallStatusManager::AnswerPendingCall()
{
TELEPHONY_LOGI("AnswerPendingCall");
std::list<sptr<CallBase>> allCallList = CallObjectManager::GetAllCallList();
for (auto call : allCallList) {
if (call->GetTelCallState() != TelCallState::CALL_STATUS_INCOMING &&
call->GetTelCallState() != TelCallState::CALL_STATUS_WAITING) {
continue;
}
bool isRtt = false;
#ifdef SUPPORT_RTT_CALL
if (call->GetCallType() == CallType::TYPE_IMS) {
sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(call.GetRefPtr());
isRtt = (imsCall->GetRttState() == RttCallState::RTT_STATE_YES);
}
#endif
if (call->GetAutoAnswerState()) {
int32_t callId = call->GetCallID();
TELEPHONY_LOGI("Auto AnswerCall callid=%{public}d", callId);
auto callControlManager = DelayedSingleton<CallControlManager>::GetInstance();
if (callControlManager == nullptr) {
return;
}
call->SetAutoAnswerState(false);
int32_t ret = callControlManager->AnswerCall(callId,
static_cast<int32_t>(call->GetVideoStateType()), isRtt);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("Auto AnswerCall failed callid=%{public}d", callId);
}
return;
}
}
return;
}
#endif
bool CallStatusManager::IsFromTheSameNumberAtTheSameTime(const sptr<CallBase> &newCall)
{
if (newCall == nullptr) {
return false;
}
std::string phoneNumber = newCall->GetAccountNumber();
sptr<CallBase> oldCall = GetOneCallObject(phoneNumber);
if (oldCall == nullptr) {
return false;
}
if ((abs(newCall->GetCallID() - oldCall->GetCallID()) != 1)) {
return false;
}
CallAttributeInfo oldAttrInfo;
oldCall->GetCallAttributeBaseInfo(oldAttrInfo);
if (oldAttrInfo.callState != TelCallState::CALL_STATUS_INCOMING) {
return false;
}
CallAttributeInfo newAttrInfo;
newCall->GetCallAttributeBaseInfo(newAttrInfo);
constexpr int32_t CALLS_COMING_MAX_INTERVAL_DURATION = 10 * 1000;
if ((newAttrInfo.callCreateTime - oldAttrInfo.callCreateTime) > CALLS_COMING_MAX_INTERVAL_DURATION) {
return false;
}
TELEPHONY_LOGI("the new call is from the same number at the same time.");
return true;
}
void CallStatusManager::ModifyEsimType()
{
auto datashareHelper = SettingsDataShareHelper::GetInstance();
if (datashareHelper == nullptr) {
return;
}
OHOS::Uri settingUri(SettingsDataShareHelper::SETTINGS_DATASHARE_URI);
std::string esimCardType = "";
constexpr const char* ESIM_TYPE_ONE_NUMBER_DUAL_TERMINAL = "1";
int32_t retCode = datashareHelper->Query(settingUri, "key_esim_card_type", esimCardType);
if ((retCode == TELEPHONY_SUCCESS) && (esimCardType == ESIM_TYPE_ONE_NUMBER_DUAL_TERMINAL ||
esimCardType == "")) {
TELEPHONY_LOGI("do not need to fix esim card type, current type: %{public}s", esimCardType.c_str());
return;
}
retCode = datashareHelper->Update(settingUri, "key_esim_card_type", ESIM_TYPE_ONE_NUMBER_DUAL_TERMINAL);
if (retCode != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("update esim card type failed, retCode: %{public}d", retCode);
return;
}
std::string manullySetState = "";
retCode = datashareHelper->Query(settingUri, "key_manually_set_net", manullySetState);
if (manullySetState == "") {
manullySetState = "000";
}
constexpr int32_t STATUS_VALUE_LEN = 3;
const char *changeStatus = manullySetState.c_str();
if (strlen(changeStatus) != STATUS_VALUE_LEN) {
return;
}
constexpr char SMARTOFF_NETWORK_MODIFIED = '1';
int32_t index = 0;
if (changeStatus[index++] != SMARTOFF_NETWORK_MODIFIED) {
retCode = datashareHelper->Update(settingUri, "key_smartoff_network_bluetooth_connection", "1");
}
if (changeStatus[index++] != SMARTOFF_NETWORK_MODIFIED) {
retCode = datashareHelper->Update(settingUri, "key_smartoff_network_not_wear", "true");
}
if (changeStatus[index++] != SMARTOFF_NETWORK_MODIFIED) {
retCode = datashareHelper->Update(settingUri, "key_smartoff_network_sleep_mode", "true");
}
}
int32_t CallStatusManager::RefreshOldCall(const CallDetailInfo &info, bool &isExistedOldCall)
{
TELEPHONY_LOGI("RefreshOldCall enter.");
sptr<CallBase> initCall = GetOneCallObjectByIndex(INIT_INDEX);
if (initCall != nullptr) {
DealFailDial(initCall);
}
sptr<CallBase> call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
if (call == nullptr) {
isExistedOldCall = false;
return TELEPHONY_SUCCESS;
}
isExistedOldCall = true;
auto oldCallType = call->GetCallType();
auto videoState = call->GetVideoStateType();
if (oldCallType != info.callType || call->GetTelCallState() != info.state || videoState != info.callMode) {
TELEPHONY_LOGI("refresh call.");
call = RefreshCallIfNecessary(call, info);
if (oldCallType != info.callType || videoState != info.callMode) {
return UpdateCallState(call, info.state);
}
}
return TELEPHONY_SUCCESS;
}
bool CallStatusManager::IsCallMotionRecognitionEnable(const std::string& key)
{
std::vector<int> activedOsAccountIds;
OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(activedOsAccountIds);
if (activedOsAccountIds.empty()) {
TELEPHONY_LOGW("activedOsAccountIds is empty");
return false;
}
int userId = activedOsAccountIds[0];
OHOS::Uri uri(
"datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_"
+ std::to_string(userId) + "?Proxy=true");
auto datashareHelper = SettingsDataShareHelper::GetInstance();
std::string is_motion_switch_on {"0"};
int resp = datashareHelper->Query(uri, key, is_motion_switch_on);
TELEPHONY_LOGI("key = %{public}s, value = %{public}s", key.c_str(), is_motion_switch_on.c_str());
if (resp == TELEPHONY_SUCCESS && is_motion_switch_on == "1") {
return true;
}
return false;
}
void CallStatusManager::StartInComingCallMotionRecognition()
{
if (GetOneCarrierCallObject(CallRunningState::CALL_RUNNING_STATE_DIALING) != nullptr ||
GetOneCarrierCallObject(CallRunningState::CALL_RUNNING_STATE_ACTIVE) != nullptr ||
GetOneCarrierCallObject(CallRunningState::CALL_RUNNING_STATE_HOLD) != nullptr) {
TELEPHONY_LOGI("has dialing active or holding call return");
return;
}
bool isPickupReduceVolumeSwitchOn =
IsCallMotionRecognitionEnable(SettingsDataShareHelper::QUERY_MOTION_PICKUP_REDUCE_KEY);
bool isFlipMuteSwitchOn = IsCallMotionRecognitionEnable(SettingsDataShareHelper::QUERY_MOTION_FLIP_MUTE_KEY);
bool isCloseToEarQuickAnswerSwitchOn =
IsCallMotionRecognitionEnable(SettingsDataShareHelper::QUERY_MOTION_CLOSE_TO_EAR_KEY);
if (isPickupReduceVolumeSwitchOn || isFlipMuteSwitchOn || isCloseToEarQuickAnswerSwitchOn) {
if (!Rosen::LoadMotionSensor()) {
TELEPHONY_LOGE("LoadMotionSensor failed");
return;
}
TELEPHONY_LOGI("LoadMotionSensor success");
if (isPickupReduceVolumeSwitchOn) {
MotionRecogntion::SubscribePickupSensor();
}
if (isFlipMuteSwitchOn) {
MotionRecogntion::SubscribeFlipSensor();
}
if (isCloseToEarQuickAnswerSwitchOn) {
MotionRecogntion::SubscribeCloseToEarSensor();
}
}
}
void CallStatusManager::StartOutGoingCallMotionRecognition()
{
bool isCloseToEarQuickAnswerSwitchOn =
IsCallMotionRecognitionEnable(SettingsDataShareHelper::QUERY_MOTION_CLOSE_TO_EAR_KEY);
if (isCloseToEarQuickAnswerSwitchOn) {
if (!Rosen::LoadMotionSensor()) {
TELEPHONY_LOGE("LoadMotionSensor failed");
return;
}
TELEPHONY_LOGI("LoadMotionSensor success");
MotionRecogntion::SubscribeCloseToEarSensor();
}
}
bool CallStatusManager::RefreshDialingStateByOtherState(sptr<CallBase> &call, const CallDetailInfo &info)
{
sptr<CallBase> initCall = GetOneCallObjectByIndex(INIT_INDEX);
if (initCall == nullptr) {
TELEPHONY_LOGE("initCall is nullptr!");
return false;
}
CallDetailInfo tempInfo = info;
tempInfo.state = TelCallState::CALL_STATUS_DIALING;
DialingHandle(tempInfo);
HandleDsdaInfo(info.accountId);
DelayedSingleton<BluetoothCallService>::GetInstance()->GetCallState();
call = GetOneCallObjectByIndexSlotIdAndCallType(info.index, info.accountId, info.callType);
if (call == nullptr) {
TELEPHONY_LOGE("after recalling dialingHandle, call still is nullptr!");
return false;
}
return true;
}
void OOBEStatusObserver::OnChange()
{
TELEPHONY_LOGE("OOBEStatusObserver::OnChange enter");
CallStatusManager::UpdateDevProvisioned();
}
void CallStatusManager::RegisterObserver()
{
if (oobeStatusObserver_ != nullptr) {
return;
}
oobeStatusObserver_ = new OOBEStatusObserver();
OHOS::Uri OOBEStatusUri(SettingsDataShareHelper::SETTINGS_DATASHARE_URI + "&key=device_provisioned");
auto helper = DelayedSingleton<SettingsDataShareHelper>().GetInstance();
if (!helper->RegisterToDataShare(OOBEStatusUri, oobeStatusObserver_)) {
TELEPHONY_LOGE("RegisterObserver failed");
}
}
int32_t CallStatusManager::GetDevProvisioned()
{
if (deviceProvisioned_ == DEVICE_PROVISION_UNDEF) {
UpdateDevProvisioned();
}
return deviceProvisioned_;
}
void CallStatusManager::UpdateDevProvisioned()
{
auto datashareHelper = SettingsDataShareHelper::GetInstance();
if (datashareHelper == nullptr) {
TELEPHONY_LOGE("datashareHelper is null");
return;
}
std::string deviceProvisioned {"0"};
OHOS::Uri uri(
"datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=device_provisioned");
int resp = datashareHelper->Query(uri, "device_provisioned", deviceProvisioned);
if (resp == TELEPHONY_SUCCESS) {
TELEPHONY_LOGI("UpdateDevProvisioned device_provisioned = %{public}s", deviceProvisioned.c_str());
if (deviceProvisioned == "0" || deviceProvisioned.empty()) {
deviceProvisioned_ = DEVICE_PROVISION_INVALID;
} else if (deviceProvisioned == "1") {
deviceProvisioned_ = DEVICE_PROVISION_VALID;
}
}
}
void CallStatusManager::PackVoipCallInfo(DialParaInfo ¶Info, const CallDetailInfo &info)
{
if (info.callType == CallType::TYPE_VOIP) {
paraInfo.voipCallInfo.voipCallId = info.voipCallInfo.voipCallId;
paraInfo.voipCallInfo.userName = info.voipCallInfo.userName;
(paraInfo.voipCallInfo.userProfile).assign(
(info.voipCallInfo.userProfile).begin(), (info.voipCallInfo.userProfile).end());
paraInfo.voipCallInfo.abilityName = info.voipCallInfo.abilityName;
paraInfo.voipCallInfo.extensionId = info.voipCallInfo.extensionId;
paraInfo.voipCallInfo.voipBundleName = info.voipCallInfo.voipBundleName;
paraInfo.voipCallInfo.showBannerForIncomingCall = info.voipCallInfo.showBannerForIncomingCall;
paraInfo.voipCallInfo.isConferenceCall = info.voipCallInfo.isConferenceCall;
paraInfo.voipCallInfo.isVoiceAnswerSupported = info.voipCallInfo.isVoiceAnswerSupported;
paraInfo.voipCallInfo.isUserMuteRingToneAllowed = info.voipCallInfo.isUserMuteRingToneAllowed;
paraInfo.voipCallInfo.isDialingAllowedDuringCarrierCall = info.voipCallInfo.isDialingAllowedDuringCarrierCall;
paraInfo.voipCallInfo.hasMicPermission = info.voipCallInfo.hasMicPermission;
paraInfo.voipCallInfo.isCapsuleSticky = info.voipCallInfo.isCapsuleSticky;
paraInfo.voipCallInfo.uid = info.voipCallInfo.uid;
}
}
#ifdef SUPPORT_RTT_CALL
void CallStatusManager::HandleRttEventInfo(const ImsRTTEventType &eventType)
{
auto controlManager = DelayedSingleton<CallControlManager>::GetInstance();
if (controlManager == nullptr) {
TELEPHONY_LOGE("CallControlManager is null");
return;
}
switch (eventType) {
case ImsRTTEventType::EVENT_RTT_CLOSED:
controlManager->UnInitRttManager();
break;
default:
break;
}
}
#endif
#ifdef CALL_MANAGER_WATCH_CALL_BLOCKING
void CallStatusManager::InitWatchSystemServiceWrapper()
{
if (watchSystemServiceHandler_ != nullptr) {
return;
}
watchSystemServiceHandler_ = dlopen("libwatch_system_native.z.so", RTLD_LAZY);
if (watchSystemServiceHandler_ == nullptr) {
TELEPHONY_LOGE("open hws so failed[%{public}s]", dlerror());
return;
}
auto getNodeFunc = (CreateWatchTelephonyNodeFuncPtr)dlsym(watchSystemServiceHandler_,
"GetWatchSystemServiceNode");
if (getNodeFunc != nullptr) {
watchTelephonyNode_ = getNodeFunc();
}
}
void CallStatusManager::DeInitWatchSystemServiceWrapper()
{
if (watchTelephonyNode_ != nullptr) {
watchTelephonyNode_ = nullptr;
}
if (watchSystemServiceHandler_ != nullptr) {
if (dlclose(watchSystemServiceHandler_) != 0) {
TELEPHONY_LOGE("unload hws sdk failed");
return;
}
watchSystemServiceHandler_ = nullptr;
}
}
#endif
}
}