/*
 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "dsoftbus_handler.h"

#include "ipc_skeleton.h"
#include "token_setproc.h"

#include "cooperate_hisysevent.h"
#include "device.h"
#include "devicestatus_define.h"
#include "utility.h"

#undef LOG_TAG
#define LOG_TAG "DSoftbusHandler"

namespace OHOS {
namespace Msdp {
namespace DeviceStatus {
namespace Cooperate {
constexpr int32_t MAX_INPUT_DEV_NUM { 100 };
constexpr int32_t INVALID_DEVICE_ID { -1 };

DSoftbusHandler::DSoftbusHandler(IContext *env)
    : env_(env)
{
    handles_ = {
        { static_cast<int32_t>(MessageId::DSOFTBUS_START_COOPERATE),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnStartCooperate(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_STOP_COOPERATE),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnStopCooperate(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_COME_BACK),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnComeBack(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_COME_BACK_WITH_OPTIONS),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnComeBackWithOptions(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_RELAY_COOPERATE),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnRelayCooperate(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_RELAY_COOPERATE_FINISHED),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnRelayCooperateFinish(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_SUBSCRIBE_MOUSE_LOCATION),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnSubscribeMouseLocation(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_UNSUBSCRIBE_MOUSE_LOCATION),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnUnSubscribeMouseLocation(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_REPLY_SUBSCRIBE_MOUSE_LOCATION),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnReplySubscribeLocation(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_REPLY_UNSUBSCRIBE_MOUSE_LOCATION),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnReplyUnSubscribeLocation(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_MOUSE_LOCATION),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnRemoteMouseLocation(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_INPUT_DEV_SYNC),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnRemoteInputDevice(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_INPUT_DEV_HOT_PLUG),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnRemoteHotPlug(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_COOPERATE_WITH_OPTIONS),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnStartCooperateWithOptions(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnRelayCooperateWithOptions(networkId, packet);}},
        { static_cast<int32_t>(MessageId::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS_FINISHED),
        [this] (const std::string &networkId, NetPacket &packet) {
            this->OnRelayCooperateWithOptionsFinish(networkId, packet);}}
    };
    observer_ = std::make_shared<DSoftbusObserver>(*this);
    CHKPV(env_);
    env_->GetDSoftbus().AddObserver(observer_);
}

DSoftbusHandler::~DSoftbusHandler()
{
    CHKPV(env_);
    env_->GetDSoftbus().RemoveObserver(observer_);
}

void DSoftbusHandler::AttachSender(Channel<CooperateEvent>::Sender sender)
{
    CALL_DEBUG_ENTER;
    std::lock_guard guard(lock_);
    sender_ = sender;
}

int32_t DSoftbusHandler::CheckDeviceOnline(const std::string &networkId)
{
    CHKPR(env_, RET_ERR);
    int32_t ret = env_->GetDSoftbus().CheckDeviceOnline(networkId);
    return ret;
}

int32_t DSoftbusHandler::OpenSession(const std::string &networkId)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    auto tokenId = OHOS::IPCSkeleton::GetCallingTokenID();
    int ret = SetFirstCallerTokenID(tokenId);
    if (ret != RET_OK) {
        FI_HILOGW("Failed to SetFirstCallerTokenID, ret:%{public}d", ret);
    }
    ret = env_->GetDSoftbus().OpenSession(networkId);
    if (ret == RET_OK) {
        env_->GetDSoftbus().StartHeartBeat(networkId);
    }
    return ret;
}

void DSoftbusHandler::CloseSession(const std::string &networkId)
{
    CALL_INFO_TRACE;
    CHKPV(env_);
    env_->GetDSoftbus().CloseSession(networkId);
}

void DSoftbusHandler::CloseAllSessions()
{
    CALL_INFO_TRACE;
    CHKPV(env_);
    env_->GetDSoftbus().CloseAllSessions();
}

int32_t DSoftbusHandler::StartCooperate(const std::string &networkId, const DSoftbusStartCooperate &event)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    NetPacket packet(MessageId::DSOFTBUS_START_COOPERATE);
    packet << event.originNetworkId << event.cursorPos.x
        << event.cursorPos.y << event.success << event.extra.priv << event.pointerSpeed
        << event.touchPadSpeed << event.uid << event.userId << event.accountId << event.needCheckSameAccount;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to write data packet");
        CooperateRadarInfo radarInfo {
            .funcName = __FUNCTION__,
            .bizState = static_cast<int32_t> (BizState::STATE_END),
            .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_SERIALIZE_INSTRUCTION),
            .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
            .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
            .errCode = static_cast<int32_t> (CooperateRadarErrCode::SERIALIZE_INSTRUCTION_FAILED),
            .hostName = "",
            .localNetId = Utility::DFXRadarAnonymize(event.originNetworkId.c_str()),
            .peerNetId = Utility::DFXRadarAnonymize(networkId.c_str())
        };
        CooperateRadar::ReportCooperateRadarInfo(radarInfo);
        return RET_ERR;
    }
    int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
    if (ret != RET_OK) {
        OnCommunicationFailure(networkId);
        CooperateRadarInfo radarInfo {
            .funcName = __FUNCTION__,
            .bizState = static_cast<int32_t> (BizState::STATE_END),
            .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_SEND_INSTRUCTION_TO_REMOTE),
            .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
            .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
            .errCode = static_cast<int32_t> (CooperateRadarErrCode::SEND_INSTRUCTION_TO_REMOTE_FAILED),
            .hostName = "",
            .localNetId = Utility::DFXRadarAnonymize(event.originNetworkId.c_str()),
            .peerNetId = Utility::DFXRadarAnonymize(networkId.c_str())
        };
        CooperateRadar::ReportCooperateRadarInfo(radarInfo);
    }
    return ret;
}

int32_t DSoftbusHandler::StartCooperateWithOptions(const std::string &networkId, const DSoftbusCooperateOptions &event)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    NetPacket packet(MessageId::DSOFTBUS_COOPERATE_WITH_OPTIONS);
    packet << event.originNetworkId << event.cooperateOptions.displayX << event.cooperateOptions.displayY
        << event.cooperateOptions.displayId << event.success << event.extra.priv << event.pointerSpeed
        << event.touchPadSpeed << event.userId << event.accountId << event.needCheckSameAccount;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to write data packet");
        CooperateRadarInfo radarInfo {
            .funcName = __FUNCTION__,
            .bizState = static_cast<int32_t> (BizState::STATE_END),
            .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_SERIALIZE_INSTRUCTION),
            .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
            .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
            .errCode = static_cast<int32_t> (CooperateRadarErrCode::SERIALIZE_INSTRUCTION_FAILED),
            .hostName = "",
            .localNetId = Utility::DFXRadarAnonymize(event.originNetworkId.c_str()),
            .peerNetId = Utility::DFXRadarAnonymize(networkId.c_str())
        };
        CooperateRadar::ReportCooperateRadarInfo(radarInfo);
        return RET_ERR;
    }
    int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
    if (ret != RET_OK) {
        OnCommunicationFailure(networkId);
        CooperateRadarInfo radarInfo {
            .funcName = __FUNCTION__,
            .bizState = static_cast<int32_t> (BizState::STATE_END),
            .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_SEND_INSTRUCTION_TO_REMOTE),
            .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
            .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
            .errCode = static_cast<int32_t> (CooperateRadarErrCode::SEND_INSTRUCTION_TO_REMOTE_FAILED),
            .hostName = "",
            .localNetId = Utility::DFXRadarAnonymize(event.originNetworkId.c_str()),
            .peerNetId = Utility::DFXRadarAnonymize(networkId.c_str())
        };
        CooperateRadar::ReportCooperateRadarInfo(radarInfo);
    }
    return ret;
}

int32_t DSoftbusHandler::StopCooperate(const std::string &networkId, const DSoftbusStopCooperate &event)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    NetPacket packet(MessageId::DSOFTBUS_STOP_COOPERATE);
    int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
    if (ret != RET_OK) {
        OnCommunicationFailure(networkId);
    }
    return ret;
}

int32_t DSoftbusHandler::ComeBack(const std::string &networkId, const DSoftbusComeBack &event)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    NetPacket packet(MessageId::DSOFTBUS_COME_BACK);
    packet << event.originNetworkId << event.cursorPos.x << event.cursorPos.y << event.extra.priv << event.uid;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to write data packet");
        return RET_ERR;
    }
    int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
    if (ret != RET_OK) {
        OnCommunicationFailure(networkId);
    }
    return ret;
}

int32_t DSoftbusHandler::ComeBackWithOptions(const std::string &networkId, const DSoftbusComeBackWithOptions &event)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    NetPacket packet(MessageId::DSOFTBUS_COME_BACK_WITH_OPTIONS);
    packet << event.originNetworkId << event.cooperateOptions.displayX  << event.cooperateOptions.displayY
        << event.cooperateOptions.displayId << event.extra.priv;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to write data packet");
        return RET_ERR;
    }
    int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
    if (ret != RET_OK) {
        OnCommunicationFailure(networkId);
    }
    return ret;
}

int32_t DSoftbusHandler::RelayCooperate(const std::string &networkId, const DSoftbusRelayCooperate &event)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    NetPacket packet(MessageId::DSOFTBUS_RELAY_COOPERATE);
    packet << event.targetNetworkId << event.pointerSpeed << event.touchPadSpeed << event.uid <<
        event.userId << event.accountId << event.needCheckSameAccount;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to write data packet");
        return RET_ERR;
    }
    int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
    if (ret != RET_OK) {
        OnCommunicationFailure(networkId);
    }
    return ret;
}

int32_t DSoftbusHandler::RelayCooperateFinish(const std::string &networkId, const DSoftbusRelayCooperateFinished &event)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    NetPacket packet(MessageId::DSOFTBUS_RELAY_COOPERATE_FINISHED);
    packet << event.targetNetworkId << event.normal << event.uid;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to write data packet");
        return RET_ERR;
    }
    int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
    if (ret != RET_OK) {
        OnCommunicationFailure(networkId);
    }
    return ret;
}

int32_t DSoftbusHandler::RelayCooperateWithOptions(const std::string &networkId, const DSoftbusRelayCooperate &event)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    NetPacket packet(MessageId::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS);
    packet << event.targetNetworkId << event.pointerSpeed << event.touchPadSpeed <<
        event.userId << event.accountId << event.needCheckSameAccount;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to write data packet");
        return RET_ERR;
    }
    int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
    if (ret != RET_OK) {
        OnCommunicationFailure(networkId);
    }
    return ret;
}

int32_t DSoftbusHandler::RelayCooperateWithOptionsFinish(const std::string &networkId,
    const DSoftbusRelayCooperateFinished &event)
{
    CALL_INFO_TRACE;
    CHKPR(env_, RET_ERR);
    NetPacket packet(MessageId::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS_FINISHED);
    packet << event.targetNetworkId << event.normal;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to write data packet");
        return RET_ERR;
    }
    int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
    if (ret != RET_OK) {
        OnCommunicationFailure(networkId);
    }
    return ret;
}

std::string DSoftbusHandler::GetLocalNetworkId()
{
    return IDSoftbusAdapter::GetLocalNetworkId();
}

void DSoftbusHandler::OnBind(const std::string &networkId)
{
    FI_HILOGI("Bind to \'%{public}s\'", Utility::Anonymize(networkId).c_str());
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_SESSION_OPENED,
        DSoftbusSessionOpened {
            .networkId = networkId
        }));
}

void DSoftbusHandler::OnShutdown(const std::string &networkId)
{
    FI_HILOGI("Connection with \'%{public}s\' shutdown", Utility::Anonymize(networkId).c_str());
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_SESSION_CLOSED,
        DSoftbusSessionClosed {
            .networkId = networkId
        }));
}

void DSoftbusHandler::OnConnected(const std::string &networkId)
{
    FI_HILOGI("Connection to \'%{public}s\' successfully", Utility::Anonymize(networkId).c_str());
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_SESSION_OPENED,
        DSoftbusSessionOpened {
            .networkId = networkId
        }));
}

bool DSoftbusHandler::OnPacket(const std::string &networkId, NetPacket &packet)
{
    CALL_DEBUG_ENTER;
    int32_t messageId = static_cast<int32_t>(packet.GetMsgId());
    auto it = handles_.find(messageId);
    if (it != handles_.end()) {
        (it->second)(networkId, packet);
        return true;
    }
    FI_HILOGD("Unsupported messageId: %{public}d from %{public}s", messageId,
        Utility::Anonymize(networkId).c_str());
    return false;
}

void DSoftbusHandler::SendEvent(const CooperateEvent &event)
{
    std::lock_guard guard(lock_);
    auto ret = sender_.Send(event);
    if (ret != Channel<CooperateEvent>::NO_ERROR) {
        FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
    }
}

void DSoftbusHandler::OnCommunicationFailure(const std::string &networkId)
{
    env_->GetDSoftbus().CloseSession(networkId);
    FI_HILOGI("Notify communication failure with peer(%{public}s)", Utility::Anonymize(networkId).c_str());
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_SESSION_CLOSED,
        DSoftbusSessionClosed {
            .networkId = networkId
        }));
}

void DSoftbusHandler::OnStartCooperate(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusStartCooperate event {
        .networkId = networkId,
    };
    packet >> event.originNetworkId >> event.cursorPos.x
        >> event.cursorPos.y >> event.success;
    CooperateRadarInfo radarInfo {
        .funcName =  __FUNCTION__,
        .bizState = static_cast<int32_t> (BizState::STATE_BEGIN),
        .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_PASSIVE),
        .hostName = "",
        .localNetId = Utility::DFXRadarAnonymize(event.originNetworkId.c_str()),
        .peerNetId = Utility::DFXRadarAnonymize(networkId.c_str())
    };
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        radarInfo.bizStage =  static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_DEASERIALIZATION);
        radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL);
        radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::PASSIVE_DEASERIALIZATION_FAILED);
        CooperateRadar::ReportCooperateRadarInfo(radarInfo);
        return;
    }
    packet >> event.extra.priv;
    if (packet.ChkRWError()) {
        event.extra.priv = 0;
    }
    packet >> event.pointerSpeed;
    if (packet.ChkRWError()) {
        event.pointerSpeed = -1;
    }
    packet >> event.touchPadSpeed;
    if (packet.ChkRWError()) {
        event.touchPadSpeed = -1;
    }
    packet >> event.uid;
    if (packet.ChkRWError()) {
        event.uid = 0;
    }
    packet >> event.userId;
    if (packet.ChkRWError()) {
        event.userId = -1;
    }
    packet >> event.accountId;
    if (packet.ChkRWError()) {
        event.accountId = "";
    }
    packet >> event.needCheckSameAccount;
    if (packet.ChkRWError()) {
        event.needCheckSameAccount = false;
    }
    FI_HILOGI("Cur pointerSpeed:%{public}d, touchPadSpeed:%{public}d, uid:%{public}d",
        event.pointerSpeed, event.touchPadSpeed, event.uid);
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_START_COOPERATE,
        event));
    radarInfo.bizStage =  static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_DEASERIALIZATION);
    radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_SUCCESS);
    radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::CALLING_COOPERATE_SUCCESS);
    CooperateRadar::ReportCooperateRadarInfo(radarInfo);
    RemoteStartCooperate();
}

void DSoftbusHandler::RemoteStartCooperate()
{
    CHKPV(env_);
    auto motionDrag = env_->GetPluginManager().LoadMotionDrag();
    if (motionDrag == nullptr) {
        FI_HILOGE("Failed to load motion drag");
        return;
    }
    motionDrag->OnRemoteStartCooperateSetPointerButtonDown();
}

void DSoftbusHandler::OnStopCooperate(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusStopCooperate event {
        .networkId = networkId,
        .normal = true,
    };
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_STOP_COOPERATE,
        event));
}

void DSoftbusHandler::OnStartCooperateWithOptions(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusCooperateOptions event {
        .networkId = networkId,
    };
    packet >> event.originNetworkId >> event.cooperateOptions.displayX
        >> event.cooperateOptions.displayY >> event.cooperateOptions.displayId
        >> event.success;
    CooperateRadarInfo radarInfo {
        .funcName =  __FUNCTION__,
        .bizState = static_cast<int32_t> (BizState::STATE_BEGIN),
        .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_PASSIVE),
        .hostName = "",
        .localNetId = Utility::DFXRadarAnonymize(event.originNetworkId.c_str()),
        .peerNetId = Utility::DFXRadarAnonymize(networkId.c_str())
    };
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        radarInfo.bizStage =  static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_DEASERIALIZATION);
        radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL);
        radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::PASSIVE_DEASERIALIZATION_FAILED);
        CooperateRadar::ReportCooperateRadarInfo(radarInfo);
        return;
    }
    packet >> event.extra.priv;
    if (packet.ChkRWError()) {
        event.extra.priv = 0;
    }
    packet >> event.pointerSpeed;
    if (packet.ChkRWError()) {
        event.pointerSpeed = -1;
    }
    packet >> event.touchPadSpeed;
    if (packet.ChkRWError()) {
        event.touchPadSpeed = -1;
    }
    packet >> event.userId;
    if (packet.ChkRWError()) {
        event.userId = -1;
    }
    packet >> event.accountId;
    if (packet.ChkRWError()) {
        event.accountId = "";
    }
    packet >> event.needCheckSameAccount;
    if (packet.ChkRWError()) {
        event.needCheckSameAccount = false;
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_COOPERATE_WITH_OPTIONS,
        event));
    radarInfo.bizStage =  static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_DEASERIALIZATION);
    radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_SUCCESS);
    radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::CALLING_COOPERATE_SUCCESS);
    CooperateRadar::ReportCooperateRadarInfo(radarInfo);
    RemoteStartCooperate();
}

void DSoftbusHandler::OnComeBack(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusComeBack event {
        .networkId = networkId,
        .success = true,
    };
    packet >> event.originNetworkId >> event.cursorPos.x >> event.cursorPos.y;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    packet >> event.extra.priv;
    if (packet.ChkRWError()) {
        event.extra.priv = 0;
    }
    packet >> event.uid;
    if (packet.ChkRWError()) {
        event.uid = 0;
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_COME_BACK,
        event));
}

void DSoftbusHandler::OnComeBackWithOptions(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusComeBackWithOptions event {
        .networkId = networkId,
        .success = true,
    };
    packet >> event.originNetworkId >> event.cooperateOptions.displayX  >>
        event.cooperateOptions.displayY >> event.cooperateOptions.displayId;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    packet >> event.extra.priv;
    if (packet.ChkRWError()) {
        event.extra.priv = 0;
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_COME_BACK_WITH_OPTIONS,
        event));
}

void DSoftbusHandler::OnRelayCooperate(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusRelayCooperate event {
        .networkId = networkId,
        .normal = true,
    };
    packet >> event.targetNetworkId;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    packet >> event.pointerSpeed;
    if (packet.ChkRWError()) {
        event.pointerSpeed = -1;
    }
    FI_HILOGI("Cur pointerSpeed:%{public}d", event.pointerSpeed);
    packet >> event.touchPadSpeed;
    if (packet.ChkRWError()) {
        event.touchPadSpeed = -1;
    }
    FI_HILOGI("Cur touchPadSpeed:%{public}d", event.touchPadSpeed);
    packet >> event.uid;
    if (packet.ChkRWError()) {
        event.uid = 0;
    }
    packet >> event.userId;
    if (packet.ChkRWError()) {
        event.userId = -1;
    }
    packet >> event.accountId;
    if (packet.ChkRWError()) {
        event.accountId = "";
    }
    packet >> event.needCheckSameAccount;
    if (packet.ChkRWError()) {
        event.needCheckSameAccount = false;
    }
    FI_HILOGI("Cur uid:%{public}d", event.uid);
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_RELAY_COOPERATE,
        event));
}

void DSoftbusHandler::OnRelayCooperateFinish(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusRelayCooperate event {
        .networkId = networkId,
    };
    packet >> event.targetNetworkId >> event.normal;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    packet >> event.uid;
    if (packet.ChkRWError()) {
        event.uid = 0;
        FI_HILOGD("Cur uid:%{public}d", event.uid);
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
        event));
}

void DSoftbusHandler::OnRelayCooperateWithOptions(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusRelayCooperate event {
        .networkId = networkId,
        .normal = true,
    };
    packet >> event.targetNetworkId;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    packet >> event.pointerSpeed;
    if (packet.ChkRWError()) {
        event.pointerSpeed = -1;
    }
    FI_HILOGI("Cur pointerSpeed:%{public}d", event.pointerSpeed);
    packet >> event.touchPadSpeed;
    if (packet.ChkRWError()) {
        event.touchPadSpeed = -1;
    }
    packet >> event.userId;
    if (packet.ChkRWError()) {
        event.userId = -1;
    }
    packet >> event.accountId;
    if (packet.ChkRWError()) {
        event.accountId = "";
    }
    packet >> event.needCheckSameAccount;
    if (packet.ChkRWError()) {
        event.needCheckSameAccount = false;
    }
    FI_HILOGI("Cur touchPadSpeed:%{public}d", event.touchPadSpeed);
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS,
        event));
}

void DSoftbusHandler::OnRelayCooperateWithOptionsFinish(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusRelayCooperate event {
        .networkId = networkId,
    };
    packet >> event.targetNetworkId >> event.normal;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS_FINISHED,
        event));
}

void DSoftbusHandler::OnSubscribeMouseLocation(const std::string &networKId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusSubscribeMouseLocation event;
    packet >> event.networkId >> event.remoteNetworkId;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_SUBSCRIBE_MOUSE_LOCATION,
        event));
}

void DSoftbusHandler::OnUnSubscribeMouseLocation(const std::string& networKId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusUnSubscribeMouseLocation event;
    packet >> event.networkId >> event.remoteNetworkId;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_UNSUBSCRIBE_MOUSE_LOCATION,
        event));
}

void DSoftbusHandler::OnReplySubscribeLocation(const std::string& networKId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusReplySubscribeMouseLocation event;
    packet >> event.networkId >> event.remoteNetworkId >> event.result;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_REPLY_SUBSCRIBE_MOUSE_LOCATION,
        event));
}

void DSoftbusHandler::OnReplyUnSubscribeLocation(const std::string& networKId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusReplyUnSubscribeMouseLocation event;
    packet >> event.networkId >> event.remoteNetworkId >> event.result;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_REPLY_UNSUBSCRIBE_MOUSE_LOCATION,
        event));
}

void DSoftbusHandler::OnRemoteMouseLocation(const std::string& networKId, NetPacket &packet)
{
    CALL_DEBUG_ENTER;
    DSoftbusSyncMouseLocation event;
    packet >> event.networkId >> event.remoteNetworkId >> event.mouseLocation.displayX >>
        event.mouseLocation.displayY >> event.mouseLocation.displayWidth >> event.mouseLocation.displayHeight;
    if (packet.ChkRWError()) {
        FI_HILOGE("Failed to read data packet");
        return;
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_MOUSE_LOCATION,
        event));
}

void DSoftbusHandler::OnRemoteInputDevice(const std::string& networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusSyncInputDevice event;
    int32_t devNum { -1 };
    packet >> devNum;
    event.networkId = networkId;
    FI_HILOGI("devNum:%{public}d", devNum);
    if (devNum <= 0 || devNum >= MAX_INPUT_DEV_NUM) {
        FI_HILOGE("Invalid devNum:%{public}d", devNum);
        return;
    }
    for (int32_t i = 0; i < devNum; i++) {
        auto device = std::make_shared<Device>(INVALID_DEVICE_ID);
        if (DeserializeDevice(device, packet) != RET_OK) {
            FI_HILOGE("DeserializeDevice failed");
            return;
        }
        event.devices.push_back(device);
    }
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_INPUT_DEV_SYNC,
        event));
}

void DSoftbusHandler::OnRemoteHotPlug(const std::string &networkId, NetPacket &packet)
{
    CALL_INFO_TRACE;
    DSoftbusHotPlugEvent event;
    packet >> event.type;
    FI_HILOGI("Hot plug type:%{public}d", event.type);
    auto device = std::make_shared<Device>(INVALID_DEVICE_ID);
    if (DeserializeDevice(device, packet) != RET_OK) {
        FI_HILOGE("DeserializeDevice failed");
        return;
    }
    event.device = device;
    SendEvent(CooperateEvent(
        CooperateEventType::DSOFTBUS_INPUT_DEV_HOT_PLUG,
        event));
}

int32_t DSoftbusHandler::DeserializeDevice(std::shared_ptr<IDevice> device, NetPacket &packet)
{
    CALL_DEBUG_ENTER;
    CHKPR(device, RET_ERR);
    int32_t data;
    std::string str;
    packet >> data;
    device->SetId(data);
    packet >> str;
    device->SetDevPath(str);
    packet >> str;
    device->SetSysPath(str);
    packet >> data;
    device->SetBus(data);
    packet >> data;
    device->SetVendor(data);
    packet >> data;
    device->SetProduct(data);
    packet >> data;
    device->SetVersion(data);
    packet >> str;
    device->SetName(str);
    packet >> str;
    device->SetPhys(str);
    packet >> str;
    device->SetUniq(str);
    bool isPointerDevice { false };
    packet >> isPointerDevice;
    if (isPointerDevice) {
        device->AddCapability(IDevice::Capability::DEVICE_CAP_POINTER);
    }
    bool isKeyboard { false };
    packet >> isKeyboard;
    if (isKeyboard) {
        device->AddCapability(IDevice::Capability::DEVICE_CAP_KEYBOARD);
    }
    int32_t keyboardType { static_cast<int32_t> (IDevice::KeyboardType::KEYBOARD_TYPE_NONE) };
    packet >> keyboardType;
    device->SetKeyboardType(static_cast<IDevice::KeyboardType>(keyboardType));
    if (packet.ChkRWError()) {
        FI_HILOGE("Packet read type failed");
        return RET_ERR;
    }
    return RET_OK;
}
} // namespace Cooperate
} // namespace DeviceStatus
} // namespace Msdp
} // namespace OHOS