/*
 * Copyright (C) 2021-2026 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_control_manager.h"
#include "cpp/task_ext.h"
#include <cstdint>
#include <securec.h>
#include "csignal"
#include <string_ex.h>

#include "app_mgr_interface.h"
#include "audio_control_manager.h"
#include "bluetooth_call_manager.h"
#include "call_ability_report_proxy.h"
#include "call_connect_ability.h"
#include "call_dialog.h"
#include "call_manager_errors.h"
#include "call_manager_hisysevent.h"
#include "call_manager_utils.h"
#include "call_number_utils.h"
#include "call_records_manager.h"
#include "call_manager_base.h"
#include "call_request_event_handler_helper.h"
#include "call_state_report_proxy.h"
#include "cellular_call_connection.h"
#include "common_type.h"
#include "ims_call.h"
#include "incoming_flash_reminder.h"
#include "iservice_registry.h"
#include "reject_call_sms.h"
#include "report_call_info_handler.h"
#include "satellite_call_control.h"
#include "telephony_log_wrapper.h"
#include "video_control_manager.h"
#include "audio_device_manager.h"
#include "distributed_call_manager.h"
#include "call_superprivacy_control_manager.h"
#include "call_voice_assistant_manager.h"
#ifdef SUPPORT_DSOFTBUS
#include "interoperable_communication_manager.h"
#include "distributed_communication_manager.h"
#endif
#include "settings_datashare_helper.h"

#ifdef ABILITY_POWER_SUPPORT
#include "power_mgr_client.h"
#endif
#ifdef NOT_SUPPORT_MULTICALL
#include "core_service_client.h"
#endif
namespace OHOS {
namespace Telephony {
std::atomic<bool> CallControlManager::alarmSeted_ = false;
const uint64_t DISCONNECT_DELAY_TIME = 1000000;
const uint64_t PENDINGHANGUP_DELAY_TIME = 30000000;
static const int32_t SATCOMM_UID = 1096;
#ifdef CALL_MANAGER_THERMAL_PROTECTION
static const int32_t THERMAL_UID = 5528;
static const int32_t CRITICAL_THERMAL_LEVEL = 4;
#endif
using namespace OHOS::EventFwk;
CallControlManager::CallControlManager()
    : callStateListenerPtr_(nullptr), CallRequestHandlerPtr_(nullptr), incomingCallWakeup_(nullptr),
      missedCallNotification_(nullptr), callSettingManagerPtr_(nullptr)
{
    dialSrcInfo_.callId = ERR_ID;
    dialSrcInfo_.number = "";
    extras_.Clear();
    dialSrcInfo_.isDialing = false;
}

CallControlManager::~CallControlManager()
{}

bool CallControlManager::Init()
{
    callStateListenerPtr_ = std::make_unique<CallStateListener>();
    CallRequestHandlerPtr_ = std::make_unique<CallRequestHandler>();
    CallRequestHandlerPtr_->Init();
    incomingCallWakeup_ = std::make_shared<IncomingCallWakeup>();
    missedCallNotification_ = std::make_shared<MissedCallNotification>();
    callSettingManagerPtr_ = std::make_unique<CallSettingManager>();
#ifdef SUPPORT_RTT_CALL
    rttCallListener_ = std::make_shared<RttCallListener>();
#endif
    if (SubscriberSaStateChange() != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SubscriberSaStateChange failed!");
    }
    DelayedSingleton<AudioControlManager>::GetInstance()->Init();
    CallStateObserve();
    auto callSuperPrivacyControlManager = DelayedSingleton<CallSuperPrivacyControlManager>::GetInstance();
    if (callSuperPrivacyControlManager != nullptr) {
        callSuperPrivacyControlManager->RegisterSuperPrivacyPolicy();
    }
    DelayedSingleton<CallStateReportProxy>::GetInstance()->UpdateCallStateForVoIPOrRestart();
    CallManagerHisysevent::InitTelephonyExtWrapper();
    return true;
}

void CallControlManager::UnInit()
{
    if (statusChangeListener_ != nullptr) {
        auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
        if (samgrProxy != nullptr) {
            samgrProxy->UnSubscribeSystemAbility(COMMON_EVENT_SERVICE_ID, statusChangeListener_);
            statusChangeListener_ = nullptr;
        }
    }
    UnregisterAppStateObserver();
    UnRegisterObserver();
    DelayedSingleton<AudioControlManager>::GetInstance()->UnInit();
    CallManagerHisysevent::DeInitTelephonyExtWrapper();
}

void CallControlManager::ReportPhoneUEInSuperPrivacy(const std::string &eventName)
{
    auto callSuperPrivacyControlManager = DelayedSingleton<CallSuperPrivacyControlManager>::GetInstance();
    if (callSuperPrivacyControlManager == nullptr) {
        return;
    }
    if (!callSuperPrivacyControlManager->CanCallWithSuperPrivacyPolicy()) {
        CallManagerHisysevent::HiWriteBehaviorEventPhoneUE(
            eventName, PNAMEID_KEY, KEY_CALL_MANAGER, PVERSIONID_KEY, "");
    }
}

int32_t CallControlManager::DialCall(std::u16string &number, AppExecFwk::PacMap &extras)
{
    sptr<CallBase> callObjectPtr = nullptr;
    std::string accountNumber(Str16ToStr8(number));
    int32_t ret = NumberLegalityCheck(accountNumber);
    if (ret != TELEPHONY_SUCCESS) {
        return ret;
    }
    auto accountId = extras.GetIntValue("accountId");
    TELEPHONY_LOGI("dialInfo slotId is[%{public}d]", accountId);
    bool isEcc = false;
    std::string newPhoneNum =
        DelayedSingleton<CallNumberUtils>::GetInstance()->RemoveSeparatorsPhoneNumber(accountNumber);
    DelayedSingleton<CallNumberUtils>::GetInstance()->CheckNumberIsEmergency(
        newPhoneNum, accountId, isEcc);
    if (isEcc) {
        extras.PutIntValue("dialScene", (int32_t)DialScene::CALL_EMERGENCY);
    }
    ret = DelayedSingleton<SatelliteCallControl>::GetInstance()->IsSatelliteSwitchEnable();
    if (ret == TELEPHONY_SUCCESS) {
        ret = DelayedSingleton<SatelliteCallControl>::GetInstance()->IsAllowedSatelliteDialCall();
        if (ret != TELEPHONY_SUCCESS) {
            return ret;
        } else {
            extras.PutIntValue("callType", (int32_t)CallType::TYPE_SATELLITE);
        }
    }
    ReportPhoneUEInSuperPrivacy(CALL_DIAL_IN_SUPER_PRIVACY);
    int32_t dialType = extras.GetIntValue("dialType");
    if (dialType == (int32_t)DialType::DIAL_BLUETOOTH_TYPE) {
        extras.PutIntValue("callType", (int32_t)CallType::TYPE_BLUETOOTH);
    }
    std::u16string newPhoneNumU16 = Str8ToStr16(newPhoneNum);
    ret = CanDial(newPhoneNumU16, extras, isEcc);
    if (ret != TELEPHONY_SUCCESS) {
        CallManagerHisysevent::WriteDialCallFaultEvent(accountId, extras.GetIntValue("callType"),
            extras.GetIntValue("videoState"), ret, "Dial policy failed");
        return ret;
    }
    SetCallTypeExtras(extras);
    // temporarily save dial information
    PackageDialInformation(extras, newPhoneNum, isEcc);
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    ret = CallRequestHandlerPtr_->DialCall();
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("DialCall failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

void CallControlManager::SetCallTypeExtras(AppExecFwk::PacMap &extras)
{
    int32_t dialType = extras.GetIntValue("dialType");
    if (dialType == (int32_t)DialType::DIAL_CARRIER_TYPE || dialType == (int32_t)DialType::DIAL_VOICE_MAIL_TYPE) {
        if (!IsSupportVideoCall(extras)) {
            extras.PutIntValue("videoState", (int32_t)VideoStateType::TYPE_VOICE);
        }
        VideoStateType videoState = (VideoStateType)extras.GetIntValue("videoState");
        if (videoState == VideoStateType::TYPE_VIDEO) {
            extras.PutIntValue("callType", (int32_t)CallType::TYPE_IMS);
        }
    }
}

int32_t CallControlManager::CanDial(std::u16string &number, AppExecFwk::PacMap &extras, bool isEcc)
{
    int32_t ret = DialPolicy(number, extras, isEcc);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("dial policy result:%{public}d", ret);
        return ret;
    }
    ret = CanDialMulityCall(extras, isEcc);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("dial policy result:%{public}d", ret);
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

void CallControlManager::PackageDialInformation(AppExecFwk::PacMap &extras, std::string accountNumber, bool isEcc)
{
    std::lock_guard<ffrt::mutex> lock(mutex_);
    dialSrcInfo_.callId = ERR_ID;
    dialSrcInfo_.number = accountNumber;
    dialSrcInfo_.isDialing = true;
    dialSrcInfo_.isEcc = isEcc;
    dialSrcInfo_.isRTT = extras.GetBooleanValue("isRTT");
    dialSrcInfo_.callType = (CallType)extras.GetIntValue("callType");
    dialSrcInfo_.accountId = extras.GetIntValue("accountId");
    dialSrcInfo_.dialType = (DialType)extras.GetIntValue("dialType");
    dialSrcInfo_.videoState = (VideoStateType)extras.GetIntValue("videoState");
    dialSrcInfo_.originalCallType = (int32_t)extras.GetIntValue("videoState");
    dialSrcInfo_.bundleName = extras.GetStringValue("bundleName");
    dialSrcInfo_.isCustomAccessibility = extras.GetBooleanValue("isCustomAccessibility", false);
    dialSrcInfo_.token = extras.GetStringValue("token");
    dialSrcInfo_.phoneIndex = extras.GetIntValue("phoneIndex");
    extras_.Clear();
    extras_ = extras;
}

sptr<CallBase> CallControlManager::GetRingCall(int32_t callId, int32_t videoState)
{
    sptr<CallBase> call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING);
    if (call == nullptr) {
        TELEPHONY_LOGE("call is nullptr");
        CallManagerHisysevent::WriteAnswerCallFaultEvent(
            INVALID_PARAMETER, callId, videoState, TELEPHONY_ERR_LOCAL_PTR_NULL, "call is nullptr");
        return nullptr;
    }
    int32_t ringCallId = callId;
    if (ringCallId == INVALID_CALLID) {
        ringCallId = call->GetCallID();
    }
    return GetOneCallObject(ringCallId);
}

int32_t CallControlManager::AnswerCall(int32_t callId, int32_t videoState, bool isRTT)
{
    StopFlashRemind();
#ifdef NOT_SUPPORT_MULTICALL
    if (HangUpOtherCall(callId)) {
        return TELEPHONY_SUCCESS;
    }
#endif
    sptr<CallBase> call = GetRingCall(callId, videoState);
    if (call == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    auto ringCallId = call->GetCallID();
    call->SetAnsweredCall(true);
    ReportPhoneUEInSuperPrivacy(CALL_ANSWER_IN_SUPER_PRIVACY);
    if (CurrentIsSuperPrivacyMode(ringCallId, videoState)) {
        return TELEPHONY_SUCCESS;
    }
    AnswerHandlerForSatelliteOrVideoCall(call, videoState);
    TELEPHONY_LOGI("report answered state");
    NotifyCallStateUpdated(call, TelCallState::CALL_STATUS_INCOMING, TelCallState::CALL_STATUS_ANSWERED);
    CarrierAndVoipConflictProcess(ringCallId, TelCallState::CALL_STATUS_ANSWERED);
    if (VoIPCallState_ != CallStateToApp::CALL_STATE_IDLE && call->GetCallType() != CallType::TYPE_VOIP) {
        EnqueueAnsweredCall(ringCallId, videoState);
        return TELEPHONY_SUCCESS;
    }
    int32_t ret = AnswerCallPolicy(ringCallId, videoState);
    if (ret != TELEPHONY_SUCCESS) {
        if (IsVoipCallExist()) {
            sendEventToVoip(CallAbilityEventId::EVENT_ANSWER_VOIP_CALL);
            return TELEPHONY_SUCCESS;
        }
        CallManagerHisysevent::WriteAnswerCallFaultEvent(
            INVALID_PARAMETER, ringCallId, videoState, ret, "AnswerCallPolicy failed");
        return ret;
    }
    CallManagerHisysevent::WriteVoipCallStatisticalEvent(ringCallId, "MtBannerAnswer");
    return HandlerAnswerCall(ringCallId, videoState, isRTT);
}

int32_t CallControlManager::HandlerAnswerCall(int32_t callId, int32_t videoState, bool isRTT)
{
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    int ret = CallRequestHandlerPtr_->AnswerCall(callId, videoState, isRTT);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("AnswerCall failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

bool CallControlManager::CurrentIsSuperPrivacyMode(int32_t callId, int32_t videoState)
{
    auto callSuperPrivacyControlManager = DelayedSingleton<CallSuperPrivacyControlManager>::GetInstance();
    if (callSuperPrivacyControlManager == nullptr) {
        return false;
    }
    bool canCallWithPrivacyPolicy = callSuperPrivacyControlManager->CanCallWithSuperPrivacyPolicy();
    if (!canCallWithPrivacyPolicy) {
        TELEPHONY_LOGI("can't answer directly, need dialog");
        DelayedSingleton<AudioControlManager>::GetInstance()->MuteRinger();
        DelayedSingleton<CallDialog>::GetInstance()->DialogConnectAnswerPrivacyModeExtension("SUPER_PRIVACY_MODE",
            callId, videoState, true);
        return true;
    }
    return false;
}

void CallControlManager::AnswerHandlerForSatelliteOrVideoCall(sptr<CallBase> &call, int32_t videoState)
{
    if (call == nullptr) {
        TELEPHONY_LOGE("call is nullptr");
        return;
    }
    if (call->GetCallType() == CallType::TYPE_IMS && videoState != static_cast<int32_t>(call->GetVideoStateType())) {
        call->SetVideoStateType(static_cast<VideoStateType>(videoState));
        sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(call.GetRefPtr());
        imsCall->InitVideoCall();
        TELEPHONY_LOGI("videoState has changed");
    }
    if (call->GetCallType() == CallType::TYPE_SATELLITE) {
        sptr<CallBase> foregroundSatelliteCall =
            CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_ACTIVE);
        if (foregroundSatelliteCall != nullptr) {
            CallRequestHandlerPtr_->HangUpCall(foregroundSatelliteCall->GetCallID());
        }
    }
}

int32_t CallControlManager::CarrierAndVoipConflictProcess(int32_t callId, TelCallState callState)
{
    if (callState != TelCallState::CALL_STATUS_ANSWERED) {
        TELEPHONY_LOGI("voip calls should be handled with only when a carrier call is answered");
        return TELEPHONY_SUCCESS;
    }
    sptr<CallBase> call = GetOneCallObject(callId);
    if (call == nullptr) {
        TELEPHONY_LOGE("CarrierAndVoipConflictProcess, call is nullptr!");
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    if (call->GetCallType() == CallType::TYPE_CS ||
        call->GetCallType() == CallType::TYPE_IMS ||
        call->GetCallType() == CallType::TYPE_SATELLITE) {
        std::list<int32_t> voipCallIdList;
        int32_t ret = GetVoipCallList(voipCallIdList);
        if (ret != TELEPHONY_SUCCESS) {
            return ret;
        }
        for (auto voipCallId : voipCallIdList) {
            sptr<CallBase> voipCall = GetOneCallObject(voipCallId);
            TelCallState voipCallState = voipCall->GetTelCallState();
            if (voipCallState == TelCallState::CALL_STATUS_INCOMING) {
                TELEPHONY_LOGI("the system is rejecting a voip call, callId = %{public}d", voipCall->GetCallID());
                ret = RejectCall(voipCallId, true, u"CarrierAndVoipConflictProcess");
            } else if (voipCallState == TelCallState::CALL_STATUS_DIALING) {
                TELEPHONY_LOGI("the system is hanging up a voip call, callId = %{public}d", voipCall->GetCallID());
                ret = HangUpCall(voipCallId);
            }
            if (ret != TELEPHONY_SUCCESS) {
                return ret;
            }
        }
        return TELEPHONY_SUCCESS;
    }
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::RejectCall(int32_t callId, bool rejectWithMessage, std::u16string textMessage)
{
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }

    if (callId == INVALID_CALLID) {
        sptr<CallBase> call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING);
        if (call == nullptr) {
            TELEPHONY_LOGE("call is nullptr");
            CallManagerHisysevent::WriteHangUpFaultEvent(
                INVALID_PARAMETER, callId, TELEPHONY_ERR_LOCAL_PTR_NULL, "Reject call is nullptr");
            return TELEPHONY_ERR_LOCAL_PTR_NULL;
        }
        callId = call->GetCallID();
    }

    int32_t ret = RejectCallPolicy(callId);
    if (ret != TELEPHONY_SUCCESS) {
        if (callId >= VOIP_CALL_MINIMUM && IsVoipCallExist()) {
            sendEventToVoip(CallAbilityEventId::EVENT_REJECT_VOIP_CALL);
            return TELEPHONY_SUCCESS;
        }
        CallManagerHisysevent::WriteHangUpFaultEvent(INVALID_PARAMETER, callId, ret, "Reject RejectCallPolicy failed");
        return ret;
    }
    std::string messageStr(Str16ToStr8(textMessage));
    StopFlashRemind();
    ret = CallRequestHandlerPtr_->RejectCall(callId, rejectWithMessage, messageStr);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("RejectCall failed!");
        return ret;
    }
    CallManagerHisysevent::WriteVoipCallStatisticalEvent(callId, "MtBannerReject");
    ReportPhoneUEInSuperPrivacy(CALL_REJECT_IN_SUPER_PRIVACY);
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::HangUpCall(int32_t callId)
{
    if (callId == INVALID_CALLID) {
        std::vector<CallRunningState> callRunningStateVec;
        callRunningStateVec.push_back(CallRunningState::CALL_RUNNING_STATE_ACTIVE);
        callRunningStateVec.push_back(CallRunningState::CALL_RUNNING_STATE_DIALING);
        callRunningStateVec.push_back(CallRunningState::CALL_RUNNING_STATE_CONNECTING);
        callRunningStateVec.push_back(CallRunningState::CALL_RUNNING_STATE_HOLD);

        for (auto &state : callRunningStateVec) {
            sptr<CallBase> call = GetOneCallObject(state);
            if (call != nullptr) {
                callId = call->GetCallID();
                break;
            }
        }

        if (callId == INVALID_CALLID) {
            TELEPHONY_LOGE("callId is INVALID_CALLID!");
            CallManagerHisysevent::WriteHangUpFaultEvent(
                INVALID_PARAMETER, callId, TELEPHONY_ERR_LOCAL_PTR_NULL, "HangUp callId is INVALID_CALLID");
            return TELEPHONY_ERR_ARGUMENT_INVALID;
        }
    }

    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    int32_t ret = HangUpPolicy(callId);
    if (ret != TELEPHONY_SUCCESS) {
        if (callId >= VOIP_CALL_MINIMUM && IsVoipCallExist()) {
            sendEventToVoip(CallAbilityEventId::EVENT_HANGUP_VOIP_CALL);
            return TELEPHONY_SUCCESS;
        }
        CallManagerHisysevent::WriteHangUpFaultEvent(INVALID_PARAMETER, callId, ret, "HangUp HangUpPolicy failed");
        return ret;
    }
    auto callRequestEventHandler = DelayedSingleton<CallRequestEventHandlerHelper>::GetInstance();
    if (callRequestEventHandler->HasPendingMo(callId)) {
        callRequestEventHandler->SetPendingMo(false, -1);
        callRequestEventHandler->SetPendingHangup(true, callId);
        TELEPHONY_LOGI("HangUpCall before dialingHandle,hangup after CLCC");
        PostPendingHangupProtectTask(callId);
        return TELEPHONY_SUCCESS;
    }
    ret = CallRequestHandlerPtr_->HangUpCall(callId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("HangUpCall failed!");
        return ret;
    }
    CallManagerHisysevent::WriteVoipCallStatisticalEvent(callId, "HungupByBanner");
    return TELEPHONY_SUCCESS;
}

void CallControlManager::PostPendingHangupProtectTask(int32_t callId)
{
    std::lock_guard<ffrt::mutex> lock(pendingHangupHandleMutex_);
    if (pendingHangupHandle_ != nullptr) {
        return;
    }
    std::weak_ptr<CallControlManager> weakPtr = shared_from_this();
    pendingHangupHandle_ = ffrt::submit_h([weakPtr, callId]() {
        auto strong = weakPtr.lock();
        if (strong == nullptr) {
            return;
        }
        auto callRequestEventHandler = DelayedSingleton<CallRequestEventHandlerHelper>::GetInstance();
        if (callRequestEventHandler != nullptr && callRequestEventHandler->HasPendingHangup(callId)) {
            sptr<CallBase> call = GetOneCallObject(callId);
            if (call != nullptr) {
                strong->DealFailDial(call);
            }
            callRequestEventHandler->SetPendingHangup(false, -1);
            std::lock_guard<ffrt::mutex> lock(strong->pendingHangupHandleMutex_);
            strong->pendingHangupHandle_ = nullptr;
            TELEPHONY_LOGI("PendingHangup timeout, clear pending state");
        }
    }, {}, {}, ffrt::task_attr().delay(PENDINGHANGUP_DELAY_TIME));
}
 
void CallControlManager::RemovePendingHangupProtectTask()
{
    std::lock_guard<ffrt::mutex> lock(pendingHangupHandleMutex_);
    if (pendingHangupHandle_ == nullptr) {
        return;
    }
    int result = ffrt::skip(pendingHangupHandle_);
    pendingHangupHandle_ = nullptr;
    if (result != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("DisconnectedHandle failed! result:%{public}d", result);
    }
}

void CallControlManager::sendEventToVoip(CallAbilityEventId eventId)
{
    CallEventInfo eventInfo;
    (void)memset_s(&eventInfo, sizeof(CallEventInfo), 0, sizeof(CallEventInfo));
    eventInfo.eventId = eventId;
    NotifyCallEventUpdated(eventInfo);
}

int32_t CallControlManager::GetCallState()
{
    CallStateToApp callState = CallStateToApp::CALL_STATE_UNKNOWN;
    if (!HasCellularCallExist() && (VoIPCallState_ == CallStateToApp::CALL_STATE_IDLE ||
        VoIPCallState_ == CallStateToApp::CALL_STATE_UNKNOWN)) {
        callState = CallStateToApp::CALL_STATE_IDLE;
    } else {
        callState = CallStateToApp::CALL_STATE_OFFHOOK;
        bool hasRingingCall = false;
        if ((HasRingingCall(hasRingingCall) == TELEPHONY_SUCCESS && hasRingingCall) ||
            VoIPCallState_ == CallStateToApp::CALL_STATE_RINGING) {
            callState = CallStateToApp::CALL_STATE_RINGING;
        }
    }
    return static_cast<int32_t>(callState);
}

int32_t CallControlManager::HoldCall(int32_t callId)
{
    int32_t ret = HoldCallPolicy(callId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("HoldCall failed!");
        return ret;
    }
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    ret = CallRequestHandlerPtr_->HoldCall(callId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("HoldCall failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::UnHoldCall(const int32_t callId)
{
    int32_t ret = UnHoldCallPolicy(callId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("UnHoldCall failed!");
        return ret;
    }
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    ret = CallRequestHandlerPtr_->UnHoldCall(callId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("UnHoldCall failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

// swap two calls state, turn active call into holding, and turn holding call into active
int32_t CallControlManager::SwitchCall(int32_t callId)
{
    int32_t ret = SwitchCallPolicy(callId);
    if (ret != TELEPHONY_SUCCESS) {
        return ret;
    }
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    ret = CallRequestHandlerPtr_->SwitchCall(callId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SwitchCall failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

bool CallControlManager::HasCall()
{
    if (VoIPCallState_ == CallStateToApp::CALL_STATE_ANSWERED ||
        VoIPCallState_ == CallStateToApp::CALL_STATE_OFFHOOK ||
        VoIPCallState_ == CallStateToApp::CALL_STATE_RINGING ||
        HasCellularCallExist()) {
        return true;
    }
    return false;
}

bool CallControlManager::HasVoipCall()
{
    return HasVoipCallExist();
}

int32_t CallControlManager::IsNewCallAllowed(bool &enabled)
{
    return IsNewCallAllowedCreate(enabled);
}

int32_t CallControlManager::IsRinging(bool &enabled)
{
    return HasRingingCall(enabled);
}

int32_t CallControlManager::HasEmergency(bool &enabled)
{
    return HasEmergencyCall(enabled);
}

bool CallControlManager::NotifyNewCallCreated(sptr<CallBase> &callObjectPtr)
{
    if (callObjectPtr == nullptr) {
        TELEPHONY_LOGE("callObjectPtr is null!");
        return false;
    }
    if (callStateListenerPtr_ != nullptr) {
        callStateListenerPtr_->NewCallCreated(callObjectPtr);
    }
    return true;
}

bool CallControlManager::NotifyCallDestroyed(const DisconnectedDetails &details)
{
    if (callStateListenerPtr_ != nullptr) {
        callStateListenerPtr_->CallDestroyed(details);
        return true;
    }
    return false;
}

bool CallControlManager::NotifyCallStateUpdated(
    sptr<CallBase> &callObjectPtr, TelCallState priorState, TelCallState nextState)
{
    if (callObjectPtr == nullptr || callStateListenerPtr_ == nullptr) {
        TELEPHONY_LOGE("NotifyCallStateUpdated null ptr!");
        return false;
    }
    HILOG_COMM_INFO("NotifyCallStateUpdated priorState:%{public}d,nextState:%{public}d", priorState, nextState);
    callStateListenerPtr_->CallStateUpdated(callObjectPtr, priorState, nextState);
    if (callObjectPtr->GetCallType() == CallType::TYPE_VOIP) {
        CallAttributeInfo info;
        callObjectPtr->GetCallAttributeInfo(info);
        CallManagerHisysevent::RecordVoipProcedure(info.voipCallInfo.voipCallId,
            VoipProcedureEvent::REPORT_CALL_STATE_TO_CALLUI, static_cast<int32_t>(nextState));
        return true;
    }
    if (IsCallActivated(priorState, nextState)) {
        TELEPHONY_LOGI("call is actived, now check and switch call to distributed audio device");
        DelayedSingleton<AudioDeviceManager>::GetInstance()->CheckAndSwitchDistributedAudioDevice();
    } else if ((priorState == TelCallState::CALL_STATUS_ACTIVE &&
        nextState == TelCallState::CALL_STATUS_DISCONNECTED) ||
        (priorState == TelCallState::CALL_STATUS_DISCONNECTING &&
        nextState == TelCallState::CALL_STATUS_DISCONNECTED)) {
        bool hasHoldCall = false;
        if ((HasHoldCall(hasHoldCall) == TELEPHONY_SUCCESS) && !hasHoldCall) {
            TELEPHONY_LOGI("call is disconnected, clear distributed call state");
            DelayedSingleton<AudioDeviceManager>::GetInstance()->OnActivedCallDisconnected();
        }
    } else if (priorState == TelCallState::CALL_STATUS_WAITING &&
        nextState == TelCallState::CALL_STATUS_ACTIVE) {
        if (DelayedSingleton<DistributedCallManager>::GetInstance()->IsDCallDeviceSwitchedOn()) {
            TELEPHONY_LOGI("answer multi-line call, need switch again.");
            DelayedSingleton<AudioDeviceManager>::GetInstance()->CheckAndSwitchDistributedAudioDevice();
        }
    }
    return true;
}

bool CallControlManager::IsCallActivated(const TelCallState& priorState, const TelCallState& nextState)
{
    return (priorState == TelCallState::CALL_STATUS_DIALING && nextState == TelCallState::CALL_STATUS_ALERTING) ||
           (priorState == TelCallState::CALL_STATUS_DIALING && nextState == TelCallState::CALL_STATUS_ACTIVE) ||
           (priorState == TelCallState::CALL_STATUS_INCOMING && nextState == TelCallState::CALL_STATUS_ACTIVE) ||
           (priorState == TelCallState::CALL_STATUS_ALERTING && nextState == TelCallState::CALL_STATUS_ACTIVE);
}

bool CallControlManager::NotifyVoipCallStateUpdated(
    CallAttributeInfo info, TelCallState priorState, TelCallState nextState)
{
    if (callStateListenerPtr_ != nullptr) {
        TELEPHONY_LOGI("NotifyVoipStateUpdated priorState:%{public}d,nextState:%{public}d", priorState, nextState);
        callStateListenerPtr_->MeeTimeStateUpdated(info, priorState, nextState);
        return true;
    }
    return false;
}

bool CallControlManager::NotifyIncomingCallAnswered(sptr<CallBase> &callObjectPtr)
{
    if (callObjectPtr == nullptr) {
        return false;
    }
    if (callStateListenerPtr_ != nullptr) {
        callStateListenerPtr_->IncomingCallActivated(callObjectPtr);
        return true;
    }
    return false;
}

bool CallControlManager::NotifyIncomingCallRejected(
    sptr<CallBase> &callObjectPtr, bool isSendSms, std::string content)
{
    if (callObjectPtr == nullptr) {
        return false;
    }
    if (callStateListenerPtr_ != nullptr) {
        callStateListenerPtr_->IncomingCallHungUp(callObjectPtr, isSendSms, content);
        return true;
    }
    return false;
}

bool CallControlManager::NotifyCallEventUpdated(CallEventInfo &info)
{
    if (callStateListenerPtr_ != nullptr) {
        callStateListenerPtr_->CallEventUpdated(info);
        return true;
    }
    return false;
}

int32_t CallControlManager::StartDtmf(int32_t callId, char str)
{
    sptr<CallBase> call = GetOneCallObject(callId);
    if (call == nullptr) {
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    if (!call->IsAliveState()) {
        return CALL_ERR_CALL_STATE_MISMATCH_OPERATION;
    }

    int32_t ret = call->StartDtmf(str);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("StartDtmf failed, return:%{public}d", ret);
    }
    ffrt::submit([str]() {
        DelayedSingleton<AudioControlManager>::GetInstance()->PlayDtmfTone(str);
    });
    return ret;
}

int32_t CallControlManager::StopDtmf(int32_t callId)
{
    sptr<CallBase> call = GetOneCallObject(callId);
    if (call == nullptr) {
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    if (!call->IsAliveState()) {
        return CALL_ERR_CALL_STATE_MISMATCH_OPERATION;
    }

    int32_t ret = call->StopDtmf();
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("StopDtmf failed, return:%{public}d", ret);
    }
    DelayedSingleton<AudioControlManager>::GetInstance()->StopDtmfTone();
    return ret;
}

int32_t CallControlManager::PostDialProceed(int32_t callId, bool proceed)
{
    sptr<CallBase> call = GetOneCallObject(callId);
    if (call == nullptr) {
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    if (!call->IsAliveState()) {
        return CALL_ERR_CALL_STATE_MISMATCH_OPERATION;
    }

    int32_t ret = call->PostDialProceed(proceed);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("PostDialProceed failed, return:%{public}d", ret);
    }
    return ret;
}

int32_t CallControlManager::GetCallWaiting(int32_t slotId)
{
    int32_t ret = CallPolicy::GetCallWaitingPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->GetCallWaiting(slotId);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::SetCallWaiting(int32_t slotId, bool activate)
{
    int32_t ret = CallPolicy::SetCallWaitingPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->SetCallWaiting(slotId, activate);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::GetCallRestriction(int32_t slotId, CallRestrictionType type)
{
    int32_t ret = CallPolicy::GetCallRestrictionPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("GetCallRestriction failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->GetCallRestriction(slotId, type);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::SetCallRestriction(int32_t slotId, CallRestrictionInfo &info)
{
    int32_t ret = CallPolicy::SetCallRestrictionPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SetCallRestriction failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->SetCallRestriction(slotId, info);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::SetCallRestrictionPassword(
    int32_t slotId, CallRestrictionType fac, const char *oldPassword, const char *newPassword)
{
    int32_t ret = CallPolicy::SetCallRestrictionPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("policy check failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->SetCallRestrictionPassword(slotId, fac, oldPassword, newPassword);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::GetCallTransferInfo(int32_t slotId, CallTransferType type)
{
    int32_t ret = CallPolicy::GetCallTransferInfoPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("GetCallTransferInfo failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->GetCallTransferInfo(slotId, type);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::SetCallTransferInfo(int32_t slotId, CallTransferInfo &info)
{
    int32_t ret = CallPolicy::SetCallTransferInfoPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SetCallTransferInfo failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->SetCallTransferInfo(slotId, info);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::CanSetCallTransferTime(int32_t slotId, bool &result)
{
    int32_t ret = CallPolicy::SetCallTransferInfoPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("[slot%{public}d] failed!", slotId);
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->CanSetCallTransferTime(slotId, result);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::SetCallPreferenceMode(int32_t slotId, int32_t mode)
{
    int32_t ret = CallPolicy::SetCallPreferenceModePolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SetCallPreferenceMode failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->SetCallPreferenceMode(slotId, mode);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

/**
 * start a telephone conference by merging three-way calls,steps as follows:
 * 1.A call B: A<---->B,set holding
 * 2.A call C: A<---->C, active
 * 3.A initial merge request by CombineConference
 * @param mainCallId:active call id
 */
int32_t CallControlManager::CombineConference(int32_t mainCallId)
{
    sptr<CallBase> mainCall = GetOneCallObject(mainCallId);
    if (mainCall == nullptr) {
        TELEPHONY_LOGE("GetOneCallObject failed, mainCallId:%{public}d", mainCallId);
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    if (mainCall->GetTelCallState() != TelCallState::CALL_STATUS_ACTIVE) {
        TELEPHONY_LOGE("mainCall state should be active ");
        return CALL_ERR_CALL_STATE_MISMATCH_OPERATION;
    }
    if (!CallObjectManager::IsCallExist(mainCall->GetCallType(), TelCallState::CALL_STATUS_HOLDING)) {
        TELEPHONY_LOGE("callType:%{public}d,callState:CALL_STATUS_HOLDING is not exist!", mainCall->GetCallType());
        return CALL_ERR_CALL_STATE_MISMATCH_OPERATION;
    }
    int32_t ret = mainCall->CanCombineConference();
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("CanCombineConference failed");
        return ret;
    }
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    ret = CallRequestHandlerPtr_->CombineConference(mainCallId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("CombineConference failed!");
    }
    return ret;
}

int32_t CallControlManager::SeparateConference(int32_t callId)
{
    sptr<CallBase> call = GetOneCallObject(callId);
    if (call == nullptr) {
        TELEPHONY_LOGE("GetOneCallObject failed, callId:%{public}d", callId);
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    int32_t ret = call->CanSeparateConference();
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("CanSeparateConference failed");
        return ret;
    }
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    ret = CallRequestHandlerPtr_->SeparateConference(callId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SeparateConference failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::KickOutFromConference(int32_t callId)
{
    sptr<CallBase> call = GetOneCallObject(callId);
    if (call == nullptr) {
        TELEPHONY_LOGE("GetOneCallObject failed, callId:%{public}d", callId);
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    int32_t ret = call->CanKickOutFromConference();
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("CanKickOutFromConference failed");
        return ret;
    }
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    ret = CallRequestHandlerPtr_->KickOutFromConference(callId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("KickOutFromConference failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::GetMainCallId(int32_t callId, int32_t &mainCallId)
{
    sptr<CallBase> call = GetOneCallObject(callId);
    if (call == nullptr) {
        TELEPHONY_LOGE("GetMainCallId failed! callId:%{public}d", callId);
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    return call->GetMainCallId(mainCallId);
}

int32_t CallControlManager::GetSubCallIdList(int32_t callId, std::vector<std::u16string> &callIdList)
{
    sptr<CallBase> call = GetOneCallObject(callId);
    if (call == nullptr) {
        TELEPHONY_LOGE("GetSubCallIdList failed! callId:%{public}d", callId);
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    return call->GetSubCallIdList(callIdList);
}

int32_t CallControlManager::GetCallIdListForConference(int32_t callId, std::vector<std::u16string> &callIdList)
{
    sptr<CallBase> call = GetOneCallObject(callId);
    if (call == nullptr) {
        TELEPHONY_LOGE("GetCallIdListForConference failed! callId:%{public}d", callId);
        return TELEPHONY_ERR_ARGUMENT_INVALID;
    }
    return call->GetCallIdListForConference(callIdList);
}

int32_t CallControlManager::GetImsConfig(int32_t slotId, ImsConfigItem item)
{
    int32_t ret = CallPolicy::GetImsConfigPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("GetImsConfig failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->GetImsConfig(slotId, item);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::SetImsConfig(int32_t slotId, ImsConfigItem item, std::u16string &value)
{
    int32_t ret = CallPolicy::SetImsConfigPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SetImsConfig failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->SetImsConfig(slotId, item, value);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::GetImsFeatureValue(int32_t slotId, FeatureType type)
{
    int32_t ret = CallPolicy::GetImsFeatureValuePolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("GetImsFeatureValue failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->GetImsFeatureValue(slotId, type);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::SetImsFeatureValue(int32_t slotId, FeatureType type, int32_t value)
{
    int32_t ret = CallPolicy::SetImsFeatureValuePolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SetImsFeatureValue failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->SetImsFeatureValue(slotId, type, value);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::EnableImsSwitch(int32_t slotId)
{
    int32_t ret = CallPolicy::EnableVoLtePolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("EnableImsSwitch failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->EnableImsSwitch(slotId);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::DisableImsSwitch(int32_t slotId)
{
    int32_t ret = CallPolicy::DisableVoLtePolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("DisableImsSwitch failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->DisableImsSwitch(slotId);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::IsImsSwitchEnabled(int32_t slotId, bool &enabled)
{
    int32_t ret = CallPolicy::IsVoLteEnabledPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("IsImsSwitchEnabled failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->IsImsSwitchEnabled(slotId, enabled);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::SetVoNRState(int32_t slotId, int32_t state)
{
    int32_t ret = CallPolicy::VoNRStatePolicy(slotId, state);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SetVoNRState failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->SetVoNRState(slotId, state);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::GetVoNRState(int32_t slotId, int32_t &state)
{
    int32_t ret = CallPolicy::IsValidSlotId(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("SetVoNRState failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        ret = callSettingManagerPtr_->GetVoNRState(slotId, state);
        if (ret == TELEPHONY_SUCCESS) {
            ret = CallPolicy::VoNRStatePolicy(slotId, state);
        }
        return ret;
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

int32_t CallControlManager::UpdateImsCallMode(int32_t callId, ImsCallMode mode)
{
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::JoinConference(int32_t callId, std::vector<std::u16string> &numberList)
{
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    std::vector<std::string> phoneNumberList(numberList.size());
    for (size_t index = 0; index < numberList.size(); ++index) {
        phoneNumberList[index] = Str16ToStr8(numberList[index]);
    }
    int32_t ret = CallPolicy::InviteToConferencePolicy(callId, phoneNumberList);
    if (ret != TELEPHONY_SUCCESS) {
        return ret;
    }
    ret = CallRequestHandlerPtr_->JoinConference(callId, phoneNumberList);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("JoinConference failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::SetMuted(bool isMute)
{
    sptr<CallBase> call = CallObjectManager::GetAudioLiveCall();
    if (call == nullptr) {
        return CALL_ERR_AUDIO_SETTING_MUTE_FAILED;
    }

    if (call->GetCallType() == CallType::TYPE_VOIP) {
        TELEPHONY_LOGI("SetMute by voip");
        CallAttributeInfo info;
        call->GetCallAttributeInfo(info);
        CallManagerHisysevent::RecordVoipProcedure(info.voipCallInfo.voipCallId,
            VoipProcedureEvent::CALLUI_SEND_UI_EVENT,
            (isMute ? static_cast<int32_t>(CalluiSendUiEventDetail::CALLUI_MUTE_VOIP)
                : static_cast<int32_t>(CalluiSendUiEventDetail::CALLUI_UNMUTE_VOIP)));
        return call->SetMute(isMute, call->GetSlotId());
    }
    if (call->GetCallType() == CallType::TYPE_IMS
        || call->GetCallType() == CallType::TYPE_CS) {
        TELEPHONY_LOGI("SetMute by ims or cs,isMute = %{public}d", isMute);
        call->SetMute(isMute, call->GetSlotId());
    }

    return DelayedSingleton<AudioControlManager>::GetInstance()->SetMute(isMute);
}

int32_t CallControlManager::MuteRinger()
{
    CallVoiceAssistantManager::GetInstance()->MuteRinger();
    return DelayedSingleton<AudioControlManager>::GetInstance()->MuteRinger();
}

int32_t CallControlManager::SetAudioDevice(const AudioDevice &audioDevice)
{
    return DelayedSingleton<AudioControlManager>::GetInstance()->SetAudioDevice(audioDevice, true);
}

int32_t CallControlManager::ControlCamera(std::u16string cameraId, int32_t callingUid, int32_t callingPid)
{
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::SetPreviewWindow(VideoWindow &window)
{
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::SetDisplayWindow(VideoWindow &window)
{
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::SetCameraZoom(float zoomRatio)
{
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::SetPausePicture(std::u16string path)
{
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::SetDeviceDirection(int32_t rotation)
{
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::IsEmergencyPhoneNumber(std::u16string &number, int32_t slotId, bool &enabled)
{
    if (IsValidSlotId(slotId)) {
        return CALL_ERR_INVALID_SLOT_ID;
    }
    std::string newPhoneNum =
        DelayedSingleton<CallNumberUtils>::GetInstance()->RemoveSeparatorsPhoneNumber(Str16ToStr8(number));
    return DelayedSingleton<CallNumberUtils>::GetInstance()->CheckNumberIsEmergency(
        newPhoneNum, slotId, enabled);
}

int32_t CallControlManager::FormatPhoneNumber(
    std::u16string &number, std::u16string &countryCode, std::u16string &formatNumber)
{
    std::string tmpStr("");
    int32_t ret = DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumber(
        Str16ToStr8(number), Str16ToStr8(countryCode), tmpStr);
    formatNumber = Str8ToStr16(tmpStr);
    return ret;
}

int32_t CallControlManager::FormatPhoneNumberToE164(
    std::u16string &number, std::u16string &countryCode, std::u16string &formatNumber)
{
    std::string tmpStr("");
    int32_t ret = DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumberToE164(
        Str16ToStr8(number), Str16ToStr8(countryCode), tmpStr);
    formatNumber = Str8ToStr16(tmpStr);
    return ret;
}

int32_t CallControlManager::CloseUnFinishedUssd(int32_t slotId)
{
    int32_t ret = CallPolicy::CloseUnFinishedUssdPolicy(slotId);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("CloseUnFinishedUssd failed!");
        return ret;
    }
    if (callSettingManagerPtr_ != nullptr) {
        return callSettingManagerPtr_->CloseUnFinishedUssd(slotId);
    } else {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
}

void CallControlManager::GetDialParaInfo(DialParaInfo &info)
{
    std::lock_guard<ffrt::mutex> lock(mutex_);
    info = dialSrcInfo_;
}

void CallControlManager::GetDialParaInfo(DialParaInfo &info, AppExecFwk::PacMap &extras)
{
    std::lock_guard<ffrt::mutex> lock(mutex_);
    info = dialSrcInfo_;
    extras = extras_;
}

void CallControlManager::handler()
{
    alarmSeted_ = false;
    TELEPHONY_LOGE("handle DisconnectAbility");
    if (!CallObjectManager::HasCallExist()) {
        DelayedSingleton<CallConnectAbility>::GetInstance()->DisconnectAbility();
    }
}

bool CallControlManager::cancel(ffrt::task_handle &handle)
{
    if (handle != nullptr) {
        TELEPHONY_LOGI("skip disconnect ability task");
        int ret = ffrt::skip(handle);
        if (ret != TELEPHONY_SUCCESS) {
            TELEPHONY_LOGE("skip task failed, ret = %{public}d", ret);
            return false;
        }
    }
    return true;
}

void CallControlManager::ConnectCallUiService(bool shouldConnect)
{
    if (shouldConnect) {
        if (alarmSeted_) {
            if (!cancel(disconnectHandle)) {
                return;
            }
            alarmSeted_ = false;
        }
        DelayedSingleton<CallConnectAbility>::GetInstance()->ConnectAbility();
        shouldDisconnect = false;
    } else {
        shouldDisconnect = true;
        if (!alarmSeted_) {
            TELEPHONY_LOGI("submit delay disconnect ability");
            disconnectHandle = ffrt::submit_h([&]() {
                handler();
            }, {}, {}, ffrt::task_attr().delay(DISCONNECT_DELAY_TIME));
            alarmSeted_ = true;
        }  else {
            if (!cancel(disconnectHandle)) {
                return;
            }
            TELEPHONY_LOGI("submit delay disconnect ability");
            disconnectHandle = ffrt::submit_h([&]() {
                handler();
            }, {}, {}, ffrt::task_attr().delay(DISCONNECT_DELAY_TIME));
        }
    }
}

bool CallControlManager::ShouldDisconnectService()
{
    return shouldDisconnect;
}

int32_t CallControlManager::RemoveMissedIncomingCallNotification()
{
    int32_t ret = DelayedSingleton<CallRecordsManager>::GetInstance()->RemoveMissedIncomingCallNotification();
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("RemoveMissedIncomingCallNotification failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::SetVoIPCallState(int32_t state)
{
    VoIPCallState_ = (CallStateToApp)state;
    std::string identity = IPCSkeleton::ResetCallingIdentity();
    DelayedSingleton<CallStateReportProxy>::GetInstance()->UpdateCallStateForVoIPOrRestart();
    CallVoiceAssistantManager::GetInstance()->UpdateVoipCallState(state);
    if (VoIPCallState_ != CallStateToApp::CALL_STATE_IDLE &&
        VoIPCallState_ != CallStateToApp::CALL_STATE_UNKNOWN) {
        RegisterAppStateObserver();
    }
    IPCSkeleton::SetCallingIdentity(identity);
    if (VoIPCallState_ == CallStateToApp::CALL_STATE_ANSWERED) {
        TELEPHONY_LOGI("VoIP answered the call, should hangup all calls");
        std::list<sptr<CallBase>> allCallList = CallObjectManager::GetAllCallList();
        for (auto call : allCallList) {
            int32_t ret = HangUpCall(call->GetCallID());
            if (ret != TELEPHONY_SUCCESS) {
                return ret;
            }
        }
    }
    if (VoIPCallState_ == CallStateToApp::CALL_STATE_OFFHOOK) {
        HangUpVoipCall();
    }
    if (VoIPCallState_ == CallStateToApp::CALL_STATE_IDLE) {
            TELEPHONY_LOGI("VoIP call state is not active");
            if (AnsweredCallQueue_.hasCall) {
                AnsweredCallQueue_.hasCall = false;
                return AnswerCall(AnsweredCallQueue_.callId, AnsweredCallQueue_.videoState);
        }
    }
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::SetVoIPCallInfo(int32_t callId, int32_t state, std::string phoneNumber)
{
    if (!IsSupportSetVoipInfo()) {
        TELEPHONY_LOGE("SetVoIPCallState is not support");
        return TELEPHONY_ERROR;
    }
    if (callId == ILLEGAL_CALLID) {
        TELEPHONY_LOGE("The calling is dead and need the call list cleared");
        ClearVoipList();
        return TELEPHONY_ERROR;
    }
    int32_t numActive = GetCallNum(TelCallState::CALL_STATUS_ACTIVE, false);
    int32_t numHeld = GetCallNum(TelCallState::CALL_STATUS_HOLDING, false);
    switch (state) {
        case (int32_t)TelCallState::CALL_STATUS_DIALING: {
            HandleVoipDialing(callId, phoneNumber);
            break;
        }
        case (int32_t)TelCallState::CALL_STATUS_IDLE: {
            HandleVoipConnected(numActive, callId);
            break;
        }
        case (int32_t)TelCallState::CALL_STATUS_INCOMING: {
            HandleVoipIncoming(numActive, callId, phoneNumber);
            break;
        }
        case (int32_t)TelCallState::CALL_STATUS_DISCONNECTED: {
            return HandleVoipDisconnected(numActive, numHeld, callId,
                state, phoneNumber);
        }
        case (int32_t)TelCallState::CALL_STATUS_ALERTING: {
            HandleVoipAlerting(callId, phoneNumber);
            break;
        }
        default:
            break;
    }
    SetVoipCallInfoInner(callId, state, phoneNumber);
    TELEPHONY_LOGI("SetVoIPCallInfo,numActive:%{public}d,numHeld:%{public}d,callState:%{public}d", numActive, numHeld,
        state);
    return DelayedSingleton<BluetoothCallManager>::GetInstance()->
        SendBtCallState(numActive, numHeld, state, phoneNumber);
}

bool CallControlManager::IsSupportSetVoipInfo()
{
    std::string readSetVoipCallInfo =
        CallManagerUtils::GetSystemParameter(KEY_CONST_TELEPHONY_READ_SET_VOIP_CALL_INFO, "");
    if (readSetVoipCallInfo.compare("false") == 0) {
        return false;
    }
    return true;
}

void CallControlManager::HandleVoipConnected(int32_t &numActive, int32_t callId)
{
    if (numActive == 0) {
        numActive = 1;
    }
    NotifyVoipCallStateUpdated(GetVoipCallInfo(), TelCallState::CALL_STATUS_INCOMING,
        TelCallState::CALL_STATUS_ACTIVE);
    UpdateOneVoipCallObjectByCallId(callId, TelCallState::CALL_STATUS_ACTIVE);
}

void CallControlManager::HandleVoipIncoming(int32_t &numActive, int32_t callId, const std::string &phoneNumber)
{
    CallAttributeInfo info;
    size_t copiedChars = phoneNumber.copy(info.accountNumber, sizeof(info.accountNumber) - 1);
    info.accountNumber[copiedChars] = '\0';
    info.callType = CallType::TYPE_VOIP;
    info.callId = callId;
    if (HasCallExist() || IsVoipCallExist()) {
        info.callState = TelCallState::CALL_STATUS_WAITING;
    } else {
        info.callState = TelCallState::CALL_STATUS_INCOMING;
    }
    info.callDirection = CallDirection::CALL_DIRECTION_IN;
    if (IsVoipCallExist() && (GetVoipCallInfo().callState == TelCallState::CALL_STATUS_ACTIVE)) {
        if (numActive == 0) {
            numActive = 1;
        }
    }
    NotifyVoipCallStateUpdated(info, TelCallState::CALL_STATUS_INCOMING, TelCallState::CALL_STATUS_INCOMING);
    AddOneVoipCallObject(info);
    bool res = DelayedSingleton<AudioDeviceManager>::GetInstance()->SetVirtualCall(false);
    TELEPHONY_LOGI("SetVirtualCall res: %{public}d.", res);
}

int32_t CallControlManager::HandleVoipDisconnected(int32_t &numActive, int32_t numHeld, int32_t callId,
    int32_t state, const std::string &phoneNumber)
{
    CallAttributeInfo info;
    size_t copiedChars = phoneNumber.copy(info.accountNumber, sizeof(info.accountNumber) - 1);
    info.accountNumber[copiedChars] = '\0';
    info.callType = CallType::TYPE_VOIP;
    info.callId = callId;
    info.callState = (TelCallState)state;
    NotifyVoipCallStateUpdated(info, TelCallState::CALL_STATUS_ACTIVE, TelCallState::CALL_STATUS_DISCONNECTED);
    DeleteOneVoipCallObject(callId);
    DelayedSingleton<BluetoothCallManager>::GetInstance()->
        SendBtCallState(numActive, numHeld, state, phoneNumber);
    int32_t carrierCallId = ERR_ID;
    IsCallExist(TelCallState::CALL_STATUS_WAITING, carrierCallId);
    bool res = DelayedSingleton<AudioDeviceManager>::GetInstance()->SetVirtualCall(true);
    TELEPHONY_LOGI("SetVirtualCall res: %{public}d.", res);
    if (carrierCallId != ERR_ID) {
        TELEPHONY_LOGI("SetVoIPCallInfo handle cs call sucessed");
        sptr<CallBase> call = GetOneCallObject(carrierCallId);
        if (call != nullptr) {
            return DelayedSingleton<BluetoothCallManager>::GetInstance()->
                SendBtCallState(0, 0, (int32_t)TelCallState::CALL_STATUS_INCOMING, call->GetAccountNumber());
        }
    }
    return DelayedSingleton<BluetoothCallManager>::GetInstance()->
        SendBtCallState(numActive, numHeld, (int32_t)TelCallState::CALL_STATUS_IDLE, "");
}

void CallControlManager::HandleVoipDialing(int32_t callId, const std::string &phoneNumber)
{
    CallAttributeInfo info;
    size_t copiedChars = phoneNumber.copy(info.accountNumber, sizeof(info.accountNumber) - 1);
    info.accountNumber[copiedChars] = '\0';
    info.callType = CallType::TYPE_VOIP;
    info.callId = callId;
    info.callState = TelCallState::CALL_STATUS_DIALING;
    info.callDirection = CallDirection::CALL_DIRECTION_OUT;
    AddOneVoipCallObject(info);
    NotifyVoipCallStateUpdated(info, TelCallState::CALL_STATUS_DIALING, TelCallState::CALL_STATUS_DIALING);
    bool res = DelayedSingleton<AudioDeviceManager>::GetInstance()->SetVirtualCall(false);
    TELEPHONY_LOGI("SetVirtualCall res = %{public}d.", res);
}

void CallControlManager::HandleVoipAlerting(int32_t callId, const std::string &phoneNumber)
{
    int32_t dialingCallId;
    if (IsVoipCallExist(TelCallState::CALL_STATUS_DIALING, dialingCallId) && (callId == dialingCallId)) {
        NotifyVoipCallStateUpdated(GetVoipCallInfo(),
            TelCallState::CALL_STATUS_DIALING, TelCallState::CALL_STATUS_ALERTING);
        UpdateOneVoipCallObjectByCallId(callId, TelCallState::CALL_STATUS_ALERTING);
        TELEPHONY_LOGI("Update VoIP to alerting.");
    } else {
        CallAttributeInfo info;
        size_t copiedChars = phoneNumber.copy(info.accountNumber, sizeof(info.accountNumber) - 1);
        info.accountNumber[copiedChars] = '\0';
        info.callType = CallType::TYPE_VOIP;
        info.callId = callId;
        info.callState = TelCallState::CALL_STATUS_ALERTING;
        info.callDirection = CallDirection::CALL_DIRECTION_OUT;
        AddOneVoipCallObject(info);
        NotifyVoipCallStateUpdated(info, TelCallState::CALL_STATUS_DIALING, TelCallState::CALL_STATUS_DIALING);
        bool res = DelayedSingleton<AudioDeviceManager>::GetInstance()->SetVirtualCall(false);
        TELEPHONY_LOGI("SetVirtualCall res = %{public}d.", res);
    }
}

int32_t CallControlManager::GetMeetimeCallState()
{
    return VoipCallInfo_.state;
}

void CallControlManager::SetVoipCallInfoInner(const int32_t callId, const int32_t state,
    const std::string phoneNumber)
{
    VoipCallInfo_.callId = callId;
    VoipCallInfo_.state = state;
    VoipCallInfo_.phoneNumber = phoneNumber;
}

int32_t CallControlManager::GetVoIPCallInfo(int32_t &callId, int32_t &state, std::string &phoneNumber)
{
    if (!IsSupportSetVoipInfo()) {
        TELEPHONY_LOGE("GetVoIPCallInfo is not support");
        return TELEPHONY_ERROR;
    }
    callId = VoipCallInfo_.callId;
    state = VoipCallInfo_.state;
    phoneNumber = VoipCallInfo_.phoneNumber;
    return TELEPHONY_SUCCESS;
}

void CallControlManager::RegisterAppStateObserver()
{
    std::lock_guard<ffrt::mutex> lock(appStateObserverMutex_);
    if (appStateObserver == nullptr) {
        appStateObserver = new (std::nothrow) ApplicationStateObserver();
        if (appStateObserver == nullptr) {
            TELEPHONY_LOGE("Failed to Create RegisterAppStateObserver Instance");
            return;
        }
        sptr<ISystemAbilityManager> samgrClient = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
        if (samgrClient == nullptr) {
            TELEPHONY_LOGE("Failed to get samgrClient");
            appStateObserver = nullptr;
            return;
        }
        appMgrProxy_ = iface_cast<AppExecFwk::IAppMgr>(samgrClient->GetSystemAbility(APP_MGR_SERVICE_ID));
        if (appMgrProxy_ == nullptr) {
            TELEPHONY_LOGE("Failed to get appMgrProxy_");
            appStateObserver = nullptr;
            samgrClient = nullptr;
            return;
        }
        appMgrProxy_->RegisterApplicationStateObserver(appStateObserver);
    }
}

int32_t CallControlManager::HangUpVoipCall()
{
    std::list<sptr<CallBase>> allCallList = CallObjectManager::GetAllCallList();
    for (auto call : allCallList) {
        if (call == nullptr || call->GetCallType() != CallType::TYPE_VOIP) {
            continue;
        }
        TelCallState voipCallState = call->GetTelCallState();
        if (voipCallState == TelCallState::CALL_STATUS_ACTIVE) {
            TELEPHONY_LOGI("the voip call with callId %{public}d is active, no need to hangup", call->GetCallID());
        } else if (voipCallState == TelCallState::CALL_STATUS_INCOMING) {
            TELEPHONY_LOGI("Reject VoipCall callId %{public}d", call->GetCallID());
            int32_t ret = RejectCall(call->GetCallID(), true, u"CarrierAndVoipConflictProcess");
            if (ret != TELEPHONY_SUCCESS) {
                TELEPHONY_LOGE("reject voip call %{public}d failed!", call->GetCallID());
                return ret;
            }
        } else {
            TELEPHONY_LOGI("HangUp VoipCall callId %{public}d", call->GetCallID());
            int32_t ret = HangUpCall(call->GetCallID());
            if (ret != TELEPHONY_SUCCESS) {
                TELEPHONY_LOGE("hangup voip call %{public}d failed!", call->GetCallID());
                return ret;
            }
        }
    }
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::GetVoIPCallState(int32_t &state)
{
    state = (int32_t)VoIPCallState_;
    return TELEPHONY_SUCCESS;
}

void CallControlManager::CallStateObserve()
{
    if (callStateListenerPtr_ == nullptr) {
        return;
    }
    std::shared_ptr<RejectCallSms> hangUpSmsPtr = std::make_shared<RejectCallSms>();
    callStateListenerPtr_->AddOneObserver(DelayedSingleton<CallAbilityReportProxy>::GetInstance());
    callStateListenerPtr_->AddOneObserver(DelayedSingleton<CallStateReportProxy>::GetInstance());
    callStateListenerPtr_->AddOneObserver(DelayedSingleton<AudioControlManager>::GetInstance());
    callStateListenerPtr_->AddOneObserver(hangUpSmsPtr);
    callStateListenerPtr_->AddOneObserver(missedCallNotification_);
    callStateListenerPtr_->AddOneObserver(incomingCallWakeup_);
    callStateListenerPtr_->AddOneObserver(DelayedSingleton<CallRecordsManager>::GetInstance());
#ifdef SUPPORT_DSOFTBUS
    callStateListenerPtr_->AddOneObserver(DelayedSingleton<DistributedCommunicationManager>::GetInstance());
    callStateListenerPtr_->AddOneObserver(DelayedSingleton<InteroperableCommunicationManager>::GetInstance());
#endif
    callStateListenerPtr_->AddOneObserver(CallVoiceAssistantManager::GetInstance());
#ifdef SUPPORT_RTT_CALL
    callStateListenerPtr_->AddOneObserver(rttCallListener_);
#endif
}

int32_t CallControlManager::AddCallLogAndNotification(sptr<CallBase> &callObjectPtr)
{
    if (callObjectPtr == nullptr) {
        TELEPHONY_LOGE("callObjectPtr is null");
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    callObjectPtr->SetAnswerType(CallAnswerType::CALL_ANSWER_MISSED);
    DelayedSingleton<CallRecordsManager>::GetInstance()
        ->CallStateUpdated(callObjectPtr, TelCallState::CALL_STATUS_INCOMING, TelCallState::CALL_STATUS_DISCONNECTED);
    if (missedCallNotification_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    missedCallNotification_->PublishMissedCallEvent(callObjectPtr);
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::AddBlockLogAndNotification(sptr<CallBase> &callObjectPtr)
{
    if (callObjectPtr == nullptr) {
        TELEPHONY_LOGE("callObjectPtr is null");
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    callObjectPtr->SetAnswerType(CallAnswerType::CALL_ANSWER_BLOCKED);
    DelayedSingleton<CallRecordsManager>::GetInstance()
        ->CallStateUpdated(callObjectPtr, TelCallState::CALL_STATUS_INCOMING, TelCallState::CALL_STATUS_DISCONNECTED);
    if (missedCallNotification_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    missedCallNotification_->PublishBlockedCallEvent(callObjectPtr);
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::NumberLegalityCheck(std::string &number)
{
    if (number.empty()) {
        TELEPHONY_LOGE("phone number is NULL!");
        return CALL_ERR_PHONE_NUMBER_EMPTY;
    }
    if (number.length() > kMaxNumberLen) {
        TELEPHONY_LOGE(
            "the number length exceeds limit,len:%{public}zu,maxLen:%{public}d", number.length(), kMaxNumberLen);
        return CALL_ERR_NUMBER_OUT_OF_RANGE;
    }
    size_t commaPos = number.find(',');
    if (commaPos != std::string::npos) {
        number = number.substr(0, commaPos);
    }
    return TELEPHONY_SUCCESS;
}

void CallControlManager::AcquireIncomingLock()
{
    if (incomingCallWakeup_ == nullptr) {
        return;
    }
    incomingCallWakeup_->AcquireIncomingLock();
}

void CallControlManager::ReleaseIncomingLock()
{
    if (incomingCallWakeup_ == nullptr) {
        return;
    }
    incomingCallWakeup_->ReleaseIncomingLock();
}

void CallControlManager::AcquireDisconnectedLock()
{
#ifdef ABILITY_POWER_SUPPORT
    if (disconnectedRunningLock_ == nullptr) {
        disconnectedRunningLock_ = PowerMgr::PowerMgrClient::GetInstance().
            CreateRunningLock("disconnectedrunninglock", PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_PHONE);
    }
    if (disconnectedRunningLock_ != nullptr) {
        disconnectedRunningLock_->Lock(DISCONNECTED_LOCK_TIMEOUT);
        TELEPHONY_LOGI("disconnectedRunningLock_ locked");
    }
#endif
}

void CallControlManager::ReleaseDisconnectedLock()
{
#ifdef ABILITY_POWER_SUPPORT
    if (disconnectedRunningLock_ == nullptr || !disconnectedRunningLock_->IsUsed()) {
        return;
    }
    disconnectedRunningLock_->UnLock();
    TELEPHONY_LOGI("disconnectedRunningLock_ unlocked");
#endif
}

void CallControlManager::DisconnectAllCalls(bool isIncludeEmergencyCall, bool isFromThermalProtection,
    bool isWaitingForResponse)
{
    std::list<sptr<CallBase>> allCallList = CallObjectManager::GetAllCallList();
    int32_t ret = -1;
    for (auto call : allCallList) {
        if (call == nullptr) {
            continue;
        }
        if (call->GetCallType() == CallType::TYPE_BLUETOOTH) {
            continue;
        }
        int32_t callDropCause = DROP_CALL_BY_POWER_OFF;
        if (call->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_RINGING) {
            ret = RejectCall(call->GetCallID(), false, Str8ToStr16(""));
        } else {
#ifdef CALL_MANAGER_THERMAL_PROTECTION
            if (!isIncludeEmergencyCall && IsEmergencyCall(call)) {
                TELEPHONY_LOGI("Emergency call in progress, skipping thermal action");
                continue;
            }
            if (isFromThermalProtection) {
                callDropCause = DROP_CALL_BY_THERMAL_PROTECTION;
            }
#endif
            ret = HangUpCall(call->GetCallID());
        }
        CallManagerHisysevent::ReportCallDropChrEvent(call->GetSlotId(), call->GetCallIndex(), callDropCause);
        call->SetApCauseReported(true);
        if (ret == TELEPHONY_SUCCESS) {
            TELEPHONY_LOGI("one call is disconnected. call state: %{public}d, callId: %{public}d",
                call->GetCallRunningState(), call->GetCallID());
        }
        if (!isWaitingForResponse) {
            ReportCallDisconnected(call);
        }
    }
}

CallControlManager::SystemAbilityListener::SystemAbilityListener() {}

void CallControlManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
{
    if (systemAbilityId != COMMON_EVENT_SERVICE_ID) {
        TELEPHONY_LOGE("systemAbilityId is not COMMON_EVENT_SERVICE_ID");
        return;
    }
    std::string identity = IPCSkeleton::ResetCallingIdentity();
    CommonBroadcastSubscriber();
    NearlinkBroadcastSubscriber();
    ContactsBroadcastSubscriber();
    SatcommBroadcastSubscriber();
    SuperPrivacyModeBroadcastSubscriber();
    HSDRBroadcastSubscriber();
    HfpBroadcastSubscriber();
    MuteKeyBroadcastSubscriber();
    TelephonyExitSTRBroadcastSubscriber();
#ifdef CALL_MANAGER_THERMAL_PROTECTION
    ThermalLevelChangedBroadcastSubscriber();
#endif
    IPCSkeleton::SetCallingIdentity(identity);
}

void CallControlManager::SystemAbilityListener::OnRemoveSystemAbility(
    int32_t systemAbilityId, const std::string &deviceId)
{
    if (systemAbilityId != COMMON_EVENT_SERVICE_ID) {
        TELEPHONY_LOGE("systemAbilityId is not COMMON_EVENT_SERVICE_ID");
        return;
    }
    std::string identity = IPCSkeleton::ResetCallingIdentity();
    for (const auto& subscriberPtr : subscriberPtrList_) {
        (void)EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriberPtr);
    }
    subscriberPtrList_.clear();
    IPCSkeleton::SetCallingIdentity(identity);
}

void CallControlManager::SystemAbilityListener::CommonBroadcastSubscriber()
{
    EventFwk::MatchingSkills matchingSkills;
    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SIM_STATE_CHANGED);
    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED);
    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_NAME_UPDATE);
    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SHUTDOWN);
    EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills);
    subscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    std::shared_ptr<CallBroadcastSubscriber> subscriberPtr = std::make_shared<CallBroadcastSubscriber>(subscriberInfo);
    subscriberPtrList_.emplace_back(subscriberPtr);
    bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriberPtr);
    TELEPHONY_LOGI("CommonBroadcastSubscriber subscribeResult = %{public}d", subscribeResult);
}

void CallControlManager::SystemAbilityListener::NearlinkBroadcastSubscriber()
{
    EventFwk::MatchingSkills matchingSkills;
    matchingSkills.AddEvent("usual.event.nearlink.remotedevice.NAME_UPDATE");
    EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills);
    subscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    subscriberInfo.SetPermission("ohos.permission.MANAGE_NEARLINK");
    std::shared_ptr<CallBroadcastSubscriber> subscriberPtr = std::make_shared<CallBroadcastSubscriber>(subscriberInfo);
    subscriberPtrList_.emplace_back(subscriberPtr);
    bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriberPtr);
    TELEPHONY_LOGI("NearlinkBroadcastSubscriber subscribeResult = %{public}d", subscribeResult);
}

void CallControlManager::SystemAbilityListener::ContactsBroadcastSubscriber()
{
    EventFwk::MatchingSkills matchingSkills;
    matchingSkills.AddEvent("event.custom.contacts.PAGE_STATE_CHANGE");
    EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills);
    subscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    subscriberInfo.SetPermission("ohos.permission.SET_TELEPHONY_STATE");
    std::shared_ptr<CallBroadcastSubscriber> subscriberPtr = std::make_shared<CallBroadcastSubscriber>(subscriberInfo);
    subscriberPtrList_.emplace_back(subscriberPtr);
    bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriberPtr);
    TELEPHONY_LOGI("ContactsBroadcastSubscriber subscribeResult = %{public}d", subscribeResult);
}

void CallControlManager::SystemAbilityListener::SatcommBroadcastSubscriber()
{
    EventFwk::MatchingSkills matchingSkills;
    matchingSkills.AddEvent("usual.event.thermal.satcomm.HIGH_TEMP_LEVEL");
    EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills);
    subscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    subscriberInfo.SetPublisherUid(SATCOMM_UID);
    std::shared_ptr<CallBroadcastSubscriber> subscriberPtr = std::make_shared<CallBroadcastSubscriber>(subscriberInfo);
    subscriberPtrList_.emplace_back(subscriberPtr);
    bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriberPtr);
    TELEPHONY_LOGI("SatcommBroadcastSubscriber subscribeResult = %{public}d", subscribeResult);
}

void CallControlManager::SystemAbilityListener::SuperPrivacyModeBroadcastSubscriber()
{
    EventFwk::MatchingSkills matchingSkills;
    matchingSkills.AddEvent("usual.event.SUPER_PRIVACY_MODE");
    EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills);
    subscriberInfo.SetPublisherBundleName("com.settings");
    subscriberInfo.SetPermission("ohos.permission.SET_TELEPHONY_STATE");
    subscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    std::shared_ptr<CallBroadcastSubscriber> subscriberPtr = std::make_shared<CallBroadcastSubscriber>(subscriberInfo);
    subscriberPtrList_.emplace_back(subscriberPtr);
    bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriberPtr);
    TELEPHONY_LOGI("SuperPrivacyModeBroadcastSubscriber subscribeResult = %{public}d",
        subscribeResult);
}

void CallControlManager::SystemAbilityListener::HSDRBroadcastSubscriber()
{
    EventFwk::MatchingSkills matchingSkillsHsdr;
    matchingSkillsHsdr.AddEvent("usual.event.HSDR_EVENT");
    EventFwk::CommonEventSubscribeInfo subscriberInfos(matchingSkillsHsdr);
    subscriberInfos.SetPublisherBundleName("com.hsdr");
    subscriberInfos.SetPermission("ohos.permission.securityguard.REPORT_SECURITY_INFO");
    subscriberInfos.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    std::shared_ptr<CallBroadcastSubscriber> subscriber = std::make_shared<CallBroadcastSubscriber>(subscriberInfos);
    subscriberPtrList_.emplace_back(subscriber);
    bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber);
    TELEPHONY_LOGI("HSDRBroadcastSubscriber subscribeResult = %{public}d", subscribeResult);
}

void CallControlManager::SystemAbilityListener::HfpBroadcastSubscriber()
{
#ifdef HFP_ASYNC_ENABLE
    EventFwk::MatchingSkills matchingSkillsHfp;
    matchingSkillsHfp.AddEvent("usual.event.bluetooth.CONNECT_HFP_HF");
    EventFwk::CommonEventSubscribeInfo subscriberInfos(matchingSkillsHfp);
    subscriberInfos.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    subscriberInfos.SetPermission("ohos.permission.MANAGE_SETTINGS");
    std::shared_ptr<CallBroadcastSubscriber> subscriber = std::make_shared<CallBroadcastSubscriber>(subscriberInfos);
    subscriberPtrList_.emplace_back(subscriber);
    bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber);
    TELEPHONY_LOGI("HfpBroadcastSubscriber subscribeResult = %{public}d", subscribeResult);
#endif
}

void CallControlManager::SystemAbilityListener::MuteKeyBroadcastSubscriber()
{
    EventFwk::MatchingSkills matchingSkills;
    matchingSkills.AddEvent("multimodal.event.MUTE_KEY_PRESS");
    EventFwk::CommonEventSubscribeInfo subscriberInfos(matchingSkills);
    subscriberInfos.SetPermission("ohos.permission.SET_TELEPHONY_STATE");
    subscriberInfos.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    std::shared_ptr<CallBroadcastSubscriber> subscriber = std::make_shared<CallBroadcastSubscriber>(subscriberInfos);
    subscriberPtrList_.emplace_back(subscriber);
    bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber);
    TELEPHONY_LOGI("MuteKeyBroadcastSubscriber subscribeResult = %{public}d", subscribeResult);
}

void CallControlManager::SystemAbilityListener::TelephonyExitSTRBroadcastSubscriber()
{
    EventFwk::MatchingSkills matchingSkills;
    matchingSkills.AddEvent("usual.event.TELEPHONY_EXIT_STR");
    EventFwk::CommonEventSubscribeInfo subscriberInfos(matchingSkills);
    subscriberInfos.SetPriority(SECOND_PRIORITY);
    subscriberInfos.SetPermission("ohos.permission.RECEIVER_STARTUP_COMPLETED");
    subscriberInfos.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    std::shared_ptr<CallBroadcastSubscriber> subscriber = std::make_shared<CallBroadcastSubscriber>(subscriberInfos);
    subscriberPtrList_.emplace_back(subscriber);
    EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber);
}

#ifdef CALL_MANAGER_THERMAL_PROTECTION
void CallControlManager::SystemAbilityListener::ThermalLevelChangedBroadcastSubscriber()
{
    EventFwk::MatchingSkills matchingSkills;
    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_THERMAL_LEVEL_CHANGED);
    EventFwk::CommonEventSubscribeInfo subscriberInfos(matchingSkills);
    subscriberInfos.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
    subscriberInfos.SetPublisherUid(THERMAL_UID);
    std::shared_ptr<CallBroadcastSubscriber> subscriber = std::make_shared<CallBroadcastSubscriber>(subscriberInfos);
    subscriberPtrList_.emplace_back(subscriber);
    bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber);
    TELEPHONY_LOGI("ThermalLevelChangedBroadcastSubscriber subscribeResult = %{public}d", subscribeResult);
}
#endif

int32_t CallControlManager::SubscriberSaStateChange()
{
    auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
    if (samgrProxy == nullptr) {
        return TELEPHONY_ERROR;
    }
    statusChangeListener_ = sptr<SystemAbilityListener>::MakeSptr();
    if (statusChangeListener_ == nullptr) {
        TELEPHONY_LOGE("statusChangeListener_ is nullptr");
        return TELEPHONY_ERROR;
    }
    int32_t ret = samgrProxy->SubscribeSystemAbility(COMMON_EVENT_SERVICE_ID, statusChangeListener_);
    TELEPHONY_LOGI("SubscriberSaStateChange ret: %{public}d", ret);
    return TELEPHONY_SUCCESS;
}

#ifdef ABILITY_MEDIA_SUPPORT
bool CallControlManager::onButtonDealing(HeadsetButtonService::ButtonEvent type)
{
    bool isRingState = false;
    sptr<CallBase> call = nullptr;

    if (GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING) != nullptr) {
        call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING);
        isRingState = true;
    } else if (GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_DIALING) != nullptr) {
        call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_DIALING);
    } else if (GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_ACTIVE) != nullptr) {
        call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_ACTIVE);
    } else if (GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_HOLD) != nullptr) {
        call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_HOLD);
    } else {
        return false;
    }

    switch (type) {
        case HeadsetButtonService::SHORT_PRESS_EVENT:
            if (isRingState) {
                call->HangUpCall();
            } else {
                call->AnswerCall(0);
            }
            break;
        case HeadsetButtonService::LONG_PRESS_EVENT:
            if (isRingState) {
                std::string str = "";
                call->RejectCall(false, str);
            } else {
                DelayedSingleton<AudioControlManager>::GetInstance()->SetMute(true);
            }
            break;
        default:
            return false;
    }
    return true;
}
#endif
#ifdef NOT_SUPPORT_MULTICALL
bool CallControlManager::HangUpOtherCall(int32_t answerCallId)
{
    if (CallObjectManager::GetCurrentCallNum() <= 1) { // only one current call
        return false;
    }
    sptr<CallBase> answerCall = CallObjectManager::GetOneCallObject(answerCallId);
    if (answerCall == nullptr || (answerCall->GetTelCallState() != TelCallState::CALL_STATUS_INCOMING &&
        answerCall->GetTelCallState() != TelCallState::CALL_STATUS_WAITING)) {
        return false;
    }
    auto answerCallType = answerCall->GetCallType();
    if (answerCallType == CallType::TYPE_BLUETOOTH) {
        HangUpOtherCallByAnswerCallID(answerCallId);
        return false;
    }
    if (answerCallType == CallType::TYPE_CS || answerCallType == CallType::TYPE_IMS) {
        bool isSupportCallHold = false;
        OperatorConfig config;
        CoreServiceClient::GetInstance().GetOperatorConfigs(answerCall->GetSlotId(), config);
        if (config.boolValue.find("support_multi_calls_bool") != config.boolValue.end()) {
            isSupportCallHold = config.boolValue["support_multi_calls_bool"];
        }
        if (!isSupportCallHold || CallObjectManager::HasBtCallWithDifferentNumber(answerCall->GetAccountNumber()) ||
            CallObjectManager::HasRttCall()) {
            HangUpOtherCallByAnswerCallID(answerCallId, true);
            return true;
        }
    }
    return false;
}

void CallControlManager::HangUpOtherCallByAnswerCallID(int32_t answerCallId, bool autoAnswerState)
{
    sptr<CallBase> answerCall = CallObjectManager::GetOneCallObject(answerCallId);
    if (answerCall != nullptr &&
        (answerCall->GetTelCallState() == TelCallState::CALL_STATUS_INCOMING ||
        answerCall->GetTelCallState() == TelCallState::CALL_STATUS_WAITING)) {
        TELEPHONY_LOGI("AutoAnswerCall callid=%{public}d", answerCallId);
        answerCall->SetAutoAnswerState(autoAnswerState);
    }
    std::list<sptr<CallBase>> allCallList = CallObjectManager::GetAllCallList();
    for (const auto& call : allCallList) {
        int32_t callId = call->GetCallID();
        if (callId == answerCallId) {
            continue;
        }
        TelCallState telCallState = call->GetTelCallState();
        if (telCallState == TelCallState::CALL_STATUS_ACTIVE ||
            telCallState == TelCallState::CALL_STATUS_DIALING ||
            telCallState == TelCallState::CALL_STATUS_ALERTING ||
            telCallState == TelCallState::CALL_STATUS_HOLDING) {
            TELEPHONY_LOGI("HangUpCall callid=%{public}d", callId);
            int32_t ret = HangUpCall(callId);
            if (ret != TELEPHONY_SUCCESS) {
                TELEPHONY_LOGE("HangUpCall fail callid=%{public}d", callId);
            }
            CallManagerHisysevent::ReportCallDropChrEvent(callId, DROP_CALL_BY_MULTI_CALL_REJECT);
        } else if (telCallState == TelCallState::CALL_STATUS_INCOMING ||
            telCallState == TelCallState::CALL_STATUS_WAITING) {
            TELEPHONY_LOGI("RejectCall callid=%{public}d", callId);
            if (answerCall != nullptr && answerCall->GetAccountNumber() == call->GetAccountNumber()) {
                continue;
            }
            int32_t ret = RejectCall(callId, false, Str8ToStr16(""));
            if (ret != TELEPHONY_SUCCESS) {
                TELEPHONY_LOGE("RejectCall fail callid=%{public}d", callId);
            }
        }
    }
}
#endif
void WearStatusObserver::OnChange()
{
    std::string wearStatus = "";
    auto settingHelper = SettingsDataShareHelper::GetInstance();
    auto callControlMgr = DelayedSingleton<CallControlManager>().GetInstance();
    if (settingHelper != nullptr) {
        OHOS::Uri settingUri(SettingsDataShareHelper::SETTINGS_DATASHARE_URI);
        settingHelper->Query(settingUri, "wear_status", wearStatus);
    }
    TELEPHONY_LOGI("OnChange wear status: %{public}s", wearStatus.c_str());
    if (wearStatus == "1") {
        callControlMgr->SetWearState(WEAR_STATUS_OFF);
    } else if (wearStatus == "2") {
        callControlMgr->SetWearState(WEAR_STATUS_ON);
    } else {
        callControlMgr->SetWearState(WEAR_STATUS_INVALID);
    }
}
void CallControlManager::RegisterObserver()
{
    if (wearStatusObserver_ != nullptr) {
        return;
    }
    wearStatusObserver_ = new (std::nothrow) WearStatusObserver();
    if (wearStatusObserver_ == nullptr) {
        TELEPHONY_LOGE("wearStatusObserver_ is null");
        return;
    }

    OHOS::Uri wearStatusUri(SettingsDataShareHelper::SETTINGS_DATASHARE_URI + "&key=wear_status");
    auto helper = DelayedSingleton<SettingsDataShareHelper>().GetInstance();
    if (!helper->RegisterToDataShare(wearStatusUri, wearStatusObserver_)) {
        TELEPHONY_LOGE("RegisterObserver failed");
    }
}

void CallControlManager::UnRegisterObserver()
{
    if (wearStatusObserver_ == nullptr) {
        return;
    }

    OHOS::Uri wearStatusUri(SettingsDataShareHelper::SETTINGS_DATASHARE_URI + "&key=wear_status");
    auto helper = DelayedSingleton<SettingsDataShareHelper>().GetInstance();
    if (!helper->UnRegisterToDataShare(wearStatusUri, wearStatusObserver_)) {
        TELEPHONY_LOGE("RegisterObserver failed");
    }
}

void CallControlManager::SetWearState(int32_t state)
{
    std::lock_guard<ffrt::mutex> lock(wearStatusMutex_);
    wearStatus_ = state;
}

bool CallControlManager::IsNotWearOnWrist()
{
    std::lock_guard<ffrt::mutex> lock(wearStatusMutex_);
    if (wearStatus_ == WEAR_STATUS_OFF) {
        return true;
    }
    return false;
}

void CallControlManager::HandleVideoRingPlayFail()
{
    sptr<CallBase> incomingCall =
        CallObjectManager::GetOneCarrierCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING);
    if (incomingCall == nullptr) {
        TELEPHONY_LOGE("incomingCall is nullptr");
        return;
    }
    ContactInfo contactInfo = incomingCall->GetCallerInfo();
    if (memset_s(&contactInfo.ringtonePath, FILE_PATH_MAX_LEN, 0, FILE_PATH_MAX_LEN) != EOK) {
        TELEPHONY_LOGE("memset_s fail.");
    }
    incomingCall->SetCallerInfo(contactInfo);
    if (CallObjectManager::IsNeedSilentInDoNotDisturbMode()) {
        TELEPHONY_LOGI("no need play system ring.");
        return;
    }
    DelayedSingleton<AudioControlManager>::GetInstance()->PlayRingtone();
}

void CallControlManager::PreloadCallUi(bool enable, int32_t callingPid)
{
    std::lock_guard<ffrt::mutex> lock(preloadedCallUiRequestPidsMutex_);
    auto it = std::find(preloadedCallUiRequestPids_.begin(), preloadedCallUiRequestPids_.end(), callingPid);
    std::string identity = IPCSkeleton::ResetCallingIdentity();
    if (enable) {
        if (it != preloadedCallUiRequestPids_.end()) {
            IPCSkeleton::SetCallingIdentity(identity);
            return;
        }
        TELEPHONY_LOGI("PreloadCallUi pid: %{public}d", callingPid);
        preloadedCallUiRequestPids_.push_back(callingPid);
        RegisterAppStateObserver();
        ConnectCallUiService(enable);
    } else {
        if (it == preloadedCallUiRequestPids_.end()) {
            IPCSkeleton::SetCallingIdentity(identity);
            return;
        }
        preloadedCallUiRequestPids_.erase(it);
        if (preloadedCallUiRequestPids_.empty()) {
            TELEPHONY_LOGI("UnloadCallUi pid: %{public}d", callingPid);
            ConnectCallUiService(enable);
        }
    }
    IPCSkeleton::SetCallingIdentity(identity);
}

void CallControlManager::UnregisterAppStateObserver()
{
    TELEPHONY_LOGI("UnregisterAppStateObserver enter");
    std::lock_guard<ffrt::mutex> lock(appStateObserverMutex_);
    if (appMgrProxy_ != nullptr && appStateObserver != nullptr) {
        appMgrProxy_->UnregisterApplicationStateObserver(appStateObserver);
        appMgrProxy_ = nullptr;
        appStateObserver = nullptr;
    }
}

void CallControlManager::StartFlashRemind()
{
    std::lock_guard<ffrt::mutex> lock(reminderMutex_);
    if (incomingFlashReminder_ == nullptr) {
        auto runner = AppExecFwk::EventRunner::Create("handler_incoming_flash_reminder");
        incomingFlashReminder_ = std::make_shared<IncomingFlashReminder>(runner,
            []() {
                TELEPHONY_LOGI("clear flash reminder");
                DelayedSingleton<CallControlManager>::GetInstance()->ClearFlashReminder();
            }
        );
    }
    incomingFlashReminder_->StartFlashRemind();
}

void CallControlManager::SetRegMmiCodeCallbackState(bool isReg)
{
    auto callAbilityReportProxy = DelayedSingleton<CallAbilityReportProxy>::GetInstance();
    if (callAbilityReportProxy != nullptr) {
        callAbilityReportProxy->SetRegMmiCodeCallbackState(isReg);
    }
}

void CallControlManager::StopFlashRemind()
{
    std::lock_guard<ffrt::mutex> lock(reminderMutex_);
    if (incomingFlashReminder_ == nullptr) {
        return;
    }
    incomingFlashReminder_->StopFlashRemind();
}

void CallControlManager::ClearFlashReminder()
{
    std::lock_guard<ffrt::mutex> lock(reminderMutex_);
    incomingFlashReminder_ = nullptr;
}

bool CallControlManager::SetVirtualCall(bool isVirtual)
{
    TELEPHONY_LOGI("Virtualcall SetVirtualCall: %{public}d.", isVirtual);
    return DelayedSingleton<AudioDeviceManager>::GetInstance()->SetVirtualCall(isVirtual);
}

void CallControlManager::SetReduceRingToneVolume(bool reduceRingToneVolume)
{
    std::lock_guard<ffrt::mutex> lock(ringToneMutex_);
    ReduceRingToneVolume_ = reduceRingToneVolume;
}

bool CallControlManager::GetReduceRingToneVolume()
{
    std::lock_guard<ffrt::mutex> lock(ringToneMutex_);
    return ReduceRingToneVolume_;
}

bool CallControlManager::EndCall()
{
    std::vector<CallRunningState> callRunningStateVec;
    callRunningStateVec.push_back(CallRunningState::CALL_RUNNING_STATE_ACTIVE);
    callRunningStateVec.push_back(CallRunningState::CALL_RUNNING_STATE_RINGING);
    callRunningStateVec.push_back(CallRunningState::CALL_RUNNING_STATE_DIALING);
    callRunningStateVec.push_back(CallRunningState::CALL_RUNNING_STATE_CONNECTING);
    callRunningStateVec.push_back(CallRunningState::CALL_RUNNING_STATE_HOLD);

    int32_t callId = INVALID_CALLID;
    int32_t ret = TELEPHONY_SUCCESS;
    for (auto &state : callRunningStateVec) {
        sptr<CallBase> call = GetOneCallObject(state);
        if (call != nullptr) {
            callId = call->GetCallID();
            if (callId == INVALID_CALLID || callId >= VOIP_CALL_MINIMUM ||
                call->GetCallType() == CallType::TYPE_VOIP) {
                continue;
            }
            CallManagerHisysevent::ReportCallDropChrEvent(callId, DROP_CALL_BY_EXTERNAL_INVOCATION);
            if (state == CallRunningState::CALL_RUNNING_STATE_RINGING) {
                ret = RejectCall(callId, false, Str8ToStr16(""));
            } else {
                ret = HangUpCall(callId);
            }
            break;
        }
    }
    return ret == TELEPHONY_SUCCESS;
}

void CallControlManager::EnqueueAnsweredCall(int32_t callId, int32_t videoState)
{
    TELEPHONY_LOGW("VoIP call is active, waiting for VoIP to disconnect");
    AnsweredCallQueue_.hasCall = true;
    AnsweredCallQueue_.callId = callId;
    AnsweredCallQueue_.videoState = videoState;
}

#ifdef SUPPORT_RTT_CALL
int32_t CallControlManager::UpdateImsRttCallMode(int32_t callId, ImsRTTCallMode mode)
{
    int32_t ret = CallPolicy::RttCallModifyPolicy(callId);
    if (ret != TELEPHONY_SUCCESS) {
        return ret;
    }
    if (CallRequestHandlerPtr_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    ret = CallRequestHandlerPtr_->UpdateImsRttCallMode(callId, mode);
    if (ret != TELEPHONY_SUCCESS) {
        TELEPHONY_LOGE("UpdateImsRttCallMode failed!");
        return ret;
    }
    return TELEPHONY_SUCCESS;
}

int32_t CallControlManager::SetRttCapability(int32_t slotId, bool isEnable)
{
    int32_t ret = CallPolicy::SetRttCapabilityPolicy(slotId, isEnable);
    if (ret != TELEPHONY_SUCCESS) {
        return ret;
    }
    if (callSettingManagerPtr_ == nullptr) {
        TELEPHONY_LOGE("callSettingManagerPtr_ is nullptr!");
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    return callSettingManagerPtr_->SetRttCapability(slotId, isEnable);
}

int32_t CallControlManager::UnInitRttManager()
{
    if (rttCallListener_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    rttCallListener_->UnInitRttManager();
    return TELEPHONY_SUCCESS;
}

void CallControlManager::RefreshRttManager(const CallDetailInfo &callInfo)
{
    if (callInfo.state != TelCallState::CALL_STATUS_ACTIVE || callInfo.callType != CallType::TYPE_IMS ||
        callInfo.rttState != RttCallState::RTT_STATE_YES) {
        return;
    }
    sptr<CallBase> currCall = CallObjectManager::GetOneCallObjectByIndexSlotIdAndCallType(
        callInfo.index, callInfo.accountId, callInfo.callType, callInfo.phoneIndex);
    if (currCall == nullptr) {
        TELEPHONY_LOGE("cannot RefreshRttManager currCall is nullptr.");
        return;
    }
    sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(currCall.GetRefPtr());
    imsCall->SetRttState(callInfo.rttState);
    imsCall->SetRttChannelId(callInfo.rttChannelId);
    if (rttCallListener_ == nullptr) {
        return;
    }
    rttCallListener_->InitRttManager(imsCall);
}

int32_t CallControlManager::SendRttMessage(const std::string &rttMessage)
{
    if (rttCallListener_ == nullptr) {
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }

    rttCallListener_->SendRttMessage(rttMessage);
    return TELEPHONY_SUCCESS;
}
#endif

int32_t CallControlManager::SetCallAudioMode(int32_t mode, int32_t scenarios)
{
    auto audioControlManager = DelayedSingleton<AudioControlManager>::GetInstance();
    if (audioControlManager == nullptr) {
        TELEPHONY_LOGE("audioControlManager is nullptr!");
        return TELEPHONY_ERR_LOCAL_PTR_NULL;
    }
    audioControlManager->SetCallAudioMode(mode, scenarios);
    return TELEPHONY_SUCCESS;
}

#ifdef CALL_MANAGER_THERMAL_PROTECTION
void CallControlManager::HandleThermalLevelChange(int32_t level)
{
    thermalLevel_ = level;
    TELEPHONY_LOGI("Received thermal level: %{public}d", level);
    if (level < CRITICAL_THERMAL_LEVEL) {
        return;
    }
    if (!HasCallExist()) {
        TELEPHONY_LOGI("No active call exists");
        return;
    }
    DisconnectAllCalls(false, true);
    TELEPHONY_LOGI("Terminating all calls due to thermal level");
}

bool CallControlManager::IsEmergencyCall(const sptr<CallBase> &call)
{
    CallAttributeInfo info;
    call->GetCallAttributeInfo(info);
    TELEPHONY_LOGI("isEcc: %{public}d, isEccContact: %{public}d", info.isEcc, info.isEccContact);
    return info.isEcc || info.isEccContact;
}

bool CallControlManager::IsThermalProtectionRequired()
{
    return (thermalLevel_ >= CRITICAL_THERMAL_LEVEL);
}
#endif
} // namespace Telephony
} // namespace OHOS