1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: Cast Session implement realization.
15 * Author: lijianzhao
16 * Create: 2022-01-25
17 */
18
19#include "cast_session_impl.h"
20
21#include <array>
22
23#include "cast_engine_errors.h"
24#include "cast_engine_log.h"
25#include "cast_device_data_manager.h"
26#include "cast_stream_manager_client.h"
27#include "cast_stream_manager_server.h"
28#include "connection_manager.h"
29#include "dm_device_info.h"
30#include "ipc_skeleton.h"
31#include "json/json.h"
32#include "mirror_player_impl.h"
33#include "permission.h"
34#include "cast_engine_dfx.h"
35
36namespace OHOS {
37namespace CastEngine {
38namespace CastEngineService {
39DEFINE_CAST_ENGINE_LABEL("Cast-SessionImpl");
40
41using CastSessionRtsp::ActionType;
42using CastSessionRtsp::DeviceTypeParamInfo;
43using CastSessionRtsp::VtpType;
44
45namespace {
46void ProcessConnectWriteWrap(const std::string& funcName,
47    ProtocolType protocolType, int sceneType, const std::string& puid)
48{
49    if (protocolType == ProtocolType::COOPERATION) {
50        HiSysEventWriteWrap(funcName, {
51            {"BIZ_SCENE", static_cast<int32_t>(BIZSceneType::DEVICE_DISCOVERY)},
52            {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_END)},
53            {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::DEVICE_DISCOVERY)},
54            {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_SUCCESS)},
55            {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
56            {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
57            {"LOCAL_SESS_NAME", ""},
58            {"PEER_SESS_NAME", ""},
59            {"PEER_UDID", puid}});
60
61        HiSysEventWriteWrap(funcName, {
62            {"BIZ_SCENE", static_cast<int32_t>(BIZSceneType::COOPERATION)},
63            {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_BEGIN)},
64            {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::COOPERATION_ESTABLISH_RTSP_CHANNEL)},
65            {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_IDLE)},
66            {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
67            {"TO_CALL_PKG", DSOFTBUS_NAME},
68            {"LOCAL_SESS_NAME", ""},
69            {"PEER_SESS_NAME", ""},
70            {"PEER_UDID", puid}});
71    } else {
72        HiSysEventWriteWrap(funcName, {
73            {"BIZ_SCENE", sceneType},
74            {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::ESTABLISH_RTSP_CHANNEL)},
75            {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_IDLE)},
76            {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
77            {"TO_CALL_PKG", DSOFTBUS_NAME},
78            {"LOCAL_SESS_NAME", ""},
79            {"PEER_SESS_NAME", ""},
80            {"PEER_UDID", ""}});
81    }
82}
83}
84
85const std::array<std::string, static_cast<size_t>(MessageId::MSG_ID_MAX)>
86    CastSessionImpl::MESSAGE_ID_STRING = {
87        "MSG_CONNECT",
88        "MSG_SETUP",
89        "MSG_SETUP_SUCCESS",
90        "MSG_SETUP_FAILED",
91        "MSG_SETUP_DONE",
92        "MSG_PLAY",
93        "MSG_PAUSE",
94        "MSG_PLAY_REQ",
95        "MSG_PAUSE_REQ",
96        "MSG_DISCONNECT",
97        "MSG_CONNECT_TIMEOUT",
98        "MSG_PROCESS_TRIGGER_REQ",
99        "MSG_UPDATE_VIDEO_SIZE",
100        "MSG_STREAM_RECV_ACTION_EVENT_FROM_PEERS",
101        "MSG_STREAM_SEND_ACTION_EVENT_TO_PEERS",
102        "MSG_PEER_RENDER_READY",
103        "MSG_ERROR",
104        "MSG_SET_CAST_MODE",
105        "MSG_READY_TO_PLAYING",
106        "MSG_MIRROR_SEND_ACTION_EVENT_TO_PEERS",
107    };
108std::atomic<int> CastSessionImpl::idCount_ = rand();
109
110CastSessionImpl::CastSessionImpl(const CastSessionProperty &property, const CastLocalDevice &localDevice)
111    : localDevice_(localDevice), property_(property)
112{
113    CLOGD("In");
114}
115
116CastSessionImpl::~CastSessionImpl()
117{
118    CLOGD("~CastSessionImpl in");
119    StopSafty(false);
120    ThreadJoin();
121    CLOGD("~CastSessionImpl out");
122}
123
124void CastSessionImpl::SetServiceCallbackForRelease(const std::function<void(int)> &callback)
125{
126    std::lock_guard<std::mutex> lock(serviceCallbackMutex_);
127    serviceCallback_ = callback;
128}
129
130int32_t CastSessionImpl::RegisterListener(sptr<ICastSessionListenerImpl> listener)
131{
132    CLOGD("Start to register session listener");
133    if (!Permission::CheckPidPermission()) {
134        return ERR_NO_PERMISSION;
135    }
136    std::unique_lock<std::mutex> lock(mutex_);
137    listeners_[IPCSkeleton::GetCallingPid()] = listener;
138    cond_.notify_all();
139    return CAST_ENGINE_SUCCESS;
140}
141
142int32_t CastSessionImpl::UnregisterListener()
143{
144    CLOGD("In");
145    std::unique_lock<std::mutex> lock(mutex_);
146    listeners_.erase(IPCSkeleton::GetCallingPid());
147    return CAST_ENGINE_SUCCESS;
148}
149
150int32_t CastSessionImpl::AddDevice(const CastRemoteDevice &remoteDevice)
151{
152    CLOGI("sessionId_ %{public}d", sessionId_);
153    auto remote = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(remoteDevice.deviceId);
154    if (remote == std::nullopt) {
155        return CAST_ENGINE_ERROR;
156    }
157    remote->sessionId = sessionId_;
158    remote->subDeviceType = remoteDevice.subDeviceType;
159    if (!AddDevice(*remote) || !ConnectionManager::GetInstance().ConnectDevice(*remote)) {
160        CLOGE("AddDevice or ConnectDevice fail");
161        return CAST_ENGINE_ERROR;
162    }
163    CLOGI("AddDevice out.");
164    return CAST_ENGINE_SUCCESS;
165}
166
167bool CastSessionImpl::AddDevice(const CastInnerRemoteDevice &remoteDevice)
168{
169    if (!Permission::CheckPidPermission()) {
170        return false;
171    }
172
173    CLOGI("In: session state: %{public}s", SESSION_STATE_STRING[static_cast<int>(sessionState_)].c_str());
174    {
175        std::unique_lock<std::mutex> lock(mutex_);
176        if (listeners_.empty()) {
177            int timeout = 5; // unit: s
178            sptr<CastSessionImpl> self(this);
179            bool result =
180                cond_.wait_for(lock, std::chrono::seconds(timeout), [self] { return !self->listeners_.empty(); });
181            if (!result) {
182                CLOGE("Wait the listener timeout");
183                return false;
184            }
185        }
186    }
187
188    WaitSinkSetProperty();
189    if (property_.protocolType == ProtocolType::HICAR || property_.protocolType == ProtocolType::SUPER_LAUNCHER) {
190        OtherAddDevice(remoteDevice);
191    } else if (property_.protocolType == ProtocolType::COOPERATION ||
192        property_.protocolType == ProtocolType::COOPERATION_LEGACY) {
193        CLOGI("cooperation scene protocolType:%x", static_cast<uint32_t>(property_.protocolType));
194        auto dmDevice = ConnectionManager::GetInstance().GetDmDeviceInfo(remoteDevice.deviceId);
195        if (remoteDevice.deviceId.compare(dmDevice.deviceId) != 0) {
196            CLOGE("Failed to get DmDeviceInfo");
197            return false;
198        }
199        std::string networkId;
200        if (!ConnectionManager::GetInstance().IsDeviceTrusted(remoteDevice.deviceId, networkId)) {
201            CLOGI("Is not a trusted device");
202            return false;
203        }
204        if (!CastDeviceDataManager::GetInstance().AddDevice(remoteDevice, dmDevice)) {
205            return false;
206        }
207    } else if (!CastDeviceDataManager::GetInstance().UpdateDevice(remoteDevice)) {
208        return false;
209    }
210
211    if (!AddRemoteDevice(CastRemoteDeviceInfo { remoteDevice, DeviceState::DISCONNECTED })) {
212        return false;
213    }
214
215    if (property_.protocolType == ProtocolType::COOPERATION ||
216        property_.protocolType == ProtocolType::COOPERATION_LEGACY ||
217        property_.protocolType == ProtocolType::HICAR || property_.protocolType == ProtocolType::SUPER_LAUNCHER) {
218        SendCastMessage(Message(MessageId::MSG_CONNECT, remoteDevice.deviceId));
219    }
220    return true;
221}
222
223void CastSessionImpl::OtherAddDevice(const CastInnerRemoteDevice &remoteDevice)
224{
225    CLOGI("hicar scene protocolType:%{public}x", static_cast<uint32_t>(property_.protocolType));
226    DmDeviceInfo dmDeviceInfo {};
227    if (strcpy_s(dmDeviceInfo.deviceId, sizeof(dmDeviceInfo.deviceId), remoteDevice.deviceId.c_str()) != EOK) {
228        CLOGE("strcpy_s fail, errno: %{public}d", errno);
229        return;
230    }
231    if (strcpy_s(dmDeviceInfo.deviceName, sizeof(dmDeviceInfo.deviceName), remoteDevice.deviceName.c_str()) != EOK) {
232        CLOGE("strcpy_s fail, errno: %{public}d", errno);
233        return;
234    }
235    if (!CastDeviceDataManager::GetInstance().AddDevice(remoteDevice, dmDeviceInfo)) {
236        CLOGW("Add device fail");
237    }
238}
239
240void CastSessionImpl::WaitSinkSetProperty()
241{
242    std::unique_lock<std::mutex> lock(mutex_);
243    if (property_.protocolType == ProtocolType::CAST_PLUS_STREAM || property_.endType != EndType::CAST_SINK) {
244        return;
245    }
246
247    int timeout = 1; // unit: s
248    sptr<CastSessionImpl> self(this);
249    bool result = setProperty_.wait_for(lock, std::chrono::seconds(timeout),
250        [self] { return self->property_.videoProperty.fps != 0; });
251    if (!result) {
252        CLOGW("Wait the SetSessionProperty timeout");
253    }
254}
255
256int32_t CastSessionImpl::RemoveDevice(const std::string &deviceId)
257{
258    CLOGI("In: session state: %{public}s", SESSION_STATE_STRING[static_cast<int>(sessionState_)].c_str());
259    if (!Permission::CheckPidPermission()) {
260        return ERR_NO_PERMISSION;
261    }
262
263    auto anonymousID = GetAnonymousDeviceID(deviceId);
264    auto sceneType = GetBIZSceneType(static_cast<int>(property_.protocolType));
265    HiSysEventWriteWrap(__func__, {
266            {"BIZ_SCENE", sceneType},
267            {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_BEGIN)},
268            {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::START_DISCONNECT)},
269            {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_SUCCESS)},
270            {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
271            {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
272            {"LOCAL_SESS_NAME", ""},
273            {"PEER_SESS_NAME", ""},
274            {"PEER_UDID", anonymousID}});
275
276    SendCastMessage(Message(MessageId::MSG_DISCONNECT, deviceId));
277    return CAST_ENGINE_SUCCESS;
278}
279
280bool CastSessionImpl::ReleaseSessionResources(pid_t pid)
281{
282    {
283        std::lock_guard<std::mutex> lock(mutex_);
284        listeners_.erase(pid);
285        if (!listeners_.empty()) {
286            return false;
287        }
288        for (auto &deviceInfo : remoteDeviceList_) {
289            RemoveDevice(deviceInfo.remoteDevice.deviceId);
290        }
291    }
292    Stop();
293    return true;
294}
295
296int32_t CastSessionImpl::CreateMirrorPlayer(sptr<IMirrorPlayerImpl> &mirrorPlayer)
297{
298    if (!Permission::CheckPidPermission()) {
299        return ERR_NO_PERMISSION;
300    }
301    auto player = MirrorPlayerGetter();
302    if (player == nullptr) {
303        auto tmp = new (std::nothrow) MirrorPlayerImpl(this);
304        if (tmp == nullptr) {
305            CLOGE("CastMirrorPlayerImpl is null");
306            return CAST_ENGINE_ERROR;
307        }
308
309        std::unique_lock<std::mutex> lock(mirrorMutex_);
310        player = tmp;
311        mirrorPlayer_ = player;
312    }
313    mirrorPlayer = player;
314    return CAST_ENGINE_SUCCESS;
315}
316
317bool CastSessionImpl::DestroyMirrorPlayer()
318{
319    std::unique_lock<std::mutex> lock(mirrorMutex_);
320    mirrorPlayer_ = nullptr;
321    return true;
322}
323
324int32_t CastSessionImpl::CreateStreamPlayer(sptr<IStreamPlayerIpc> &streamPlayer)
325{
326    if (!Permission::CheckPidPermission()) {
327        return ERR_NO_PERMISSION;
328    }
329    auto streamManager = CreateStreamPlayerManager();
330    if (!streamManager) {
331        CLOGE("streamManager is null");
332        return CAST_ENGINE_ERROR;
333    }
334    streamPlayer = streamManager->CreateStreamPlayer([this]() { DestroyStreamPlayer(); });
335    return CAST_ENGINE_SUCCESS;
336}
337
338std::shared_ptr<ICastStreamManager> CastSessionImpl::CreateStreamPlayerManager()
339{
340    std::unique_lock<std::mutex> lock(streamMutex_);
341    bool isDoubleFrame = CastDeviceDataManager::GetInstance().IsDoubleFrameDevice(GetCurrentRemoteDeviceId());
342    CLOGI("CreateStreamPlayerManager isDoubleFrame:%{public}d", static_cast<int>(isDoubleFrame));
343    isDoubleFrame = false;
344    if (!streamManager_) {
345        if (property_.endType == EndType::CAST_SOURCE) {
346            streamManager_ = std::make_shared<CastStreamManagerClient>(std::make_shared<CastStreamListenerImpl>(this),
347                isDoubleFrame);
348        } else {
349            streamManager_ = std::make_shared<CastStreamManagerServer>(std::make_shared<CastStreamListenerImpl>(this));
350        }
351    }
352    return streamManager_;
353}
354
355bool CastSessionImpl::DestroyStreamPlayer()
356{
357    std::unique_lock<std::mutex> lock(streamMutex_);
358    streamManager_ = nullptr;
359    return true;
360}
361
362int32_t CastSessionImpl::Release()
363{
364    if (!Permission::CheckPidPermission()) {
365        return ERR_NO_PERMISSION;
366    }
367    {
368        std::lock_guard<std::mutex> lock(mutex_);
369        for (auto &deviceInfo : remoteDeviceList_) {
370            RemoveDevice(deviceInfo.remoteDevice.deviceId);
371        }
372    }
373    std::lock_guard<std::mutex> lock(serviceCallbackMutex_);
374    if (!serviceCallback_) {
375        CLOGE("serviceCallback is null");
376        return CAST_ENGINE_ERROR;
377    }
378    serviceCallback_(sessionId_);
379    return CAST_ENGINE_SUCCESS;
380}
381
382int32_t CastSessionImpl::StartAuth(const AuthInfo &authInfo)
383{
384    if (!Permission::CheckPidPermission()) {
385        return ERR_NO_PERMISSION;
386    }
387    static_cast<void>(authInfo);
388    return CAST_ENGINE_ERROR;
389}
390
391int32_t CastSessionImpl::GetSessionId(std::string &sessionId)
392{
393    if (!Permission::CheckPidPermission()) {
394        return ERR_NO_PERMISSION;
395    }
396    std::lock_guard<std::mutex> lock(mutex_);
397    if (!remoteDeviceList_.empty() &&
398        remoteDeviceList_.front().remoteDevice.channelType == ChannelType::LEGACY_CHANNEL) {
399        CLOGD("tcp get rtsp port");
400        sessionId = std::to_string(rtspPort_);
401        return CAST_ENGINE_SUCCESS;
402    }
403    sessionId = std::to_string(sessionId_);
404    return CAST_ENGINE_SUCCESS;
405}
406
407int32_t CastSessionImpl::Play(const std::string &deviceId)
408{
409    if (!Permission::CheckPidPermission()) {
410        return ERR_NO_PERMISSION;
411    }
412    CLOGI("Session state: %{public}s", SESSION_STATE_STRING[static_cast<int>(sessionState_)].c_str());
413    SendCastMessage(Message(MessageId::MSG_PLAY, deviceId));
414    return CAST_ENGINE_SUCCESS;
415}
416
417int32_t CastSessionImpl::Pause(const std::string &deviceId)
418{
419    if (!Permission::CheckPidPermission()) {
420        return ERR_NO_PERMISSION;
421    }
422    CLOGI("Session state: %{public}s", SESSION_STATE_STRING[static_cast<int>(sessionState_)].c_str());
423    SendCastMessage(Message(MessageId::MSG_PAUSE, deviceId));
424    return CAST_ENGINE_SUCCESS;
425}
426
427int32_t CastSessionImpl::GetDeviceState(const std::string &deviceId, DeviceState &deviceState)
428{
429    if (!Permission::CheckPidPermission()) {
430        return ERR_NO_PERMISSION;
431    }
432    auto deviceInfo = FindRemoteDevice(deviceId);
433    DeviceState state = DeviceState::DISCONNECTED;
434    if (deviceInfo != nullptr) {
435        state = deviceInfo->deviceState;
436    }
437    CLOGI("device state: %{public}s", DEVICE_STATE_STRING[static_cast<int>(state)].c_str());
438    deviceState = state;
439    return CAST_ENGINE_SUCCESS;
440}
441
442int32_t CastSessionImpl::SetSessionProperty(const CastSessionProperty &property)
443{
444    if (!Permission::CheckPidPermission()) {
445        return ERR_NO_PERMISSION;
446    }
447    std::unique_lock<std::mutex> lock(mutex_);
448    if (property_.protocolType != property.protocolType || property_.endType != property.endType) {
449        CLOGE("Wrong protocol type:%d or end type:%d", property.protocolType, property.endType);
450        return CAST_ENGINE_ERROR;
451    }
452    property_ = property;
453    setProperty_.notify_all();
454    CLOGD("video: width-%{public}u, height-%{public}u, fps-%{public}u; audio: sample_rate-%{public}u, "
455        "channels-%{public}u windowWidth-%{public}u, windowHeight-%{public}u",
456        property.videoProperty.videoWidth, property.videoProperty.videoHeight, property.videoProperty.fps,
457        property.audioProperty.sampleRate, property.audioProperty.channelConfig,
458        property.windowProperty.width, property.windowProperty.height);
459    return CAST_ENGINE_SUCCESS;
460}
461
462int32_t CastSessionImpl::SetSurface(sptr<IBufferProducer> producer)
463{
464    if (!Permission::CheckPidPermission()) {
465        return ERR_NO_PERMISSION;
466    }
467    CLOGD("SetSurface in");
468    return CAST_ENGINE_SUCCESS;
469}
470
471int32_t CastSessionImpl::DeliverInputEvent(const OHRemoteControlEvent &event)
472{
473    if (!Permission::CheckPidPermission()) {
474        return ERR_NO_PERMISSION;
475    }
476    CLOGD("DeliverInputEvent in.");
477    if (sessionState_ != SessionState::PLAYING) {
478        CLOGE("DeliverInputEvent failed, not playing.");
479        return ERR_SESSION_STATE_NOT_MATCH;
480    }
481    return CAST_ENGINE_SUCCESS;
482}
483
484int32_t CastSessionImpl::InjectEvent(const OHRemoteControlEvent &event)
485{
486    if (!Permission::CheckPidPermission()) {
487        return ERR_NO_PERMISSION;
488    }
489    CLOGD("InjectEvent in.");
490    if (sessionState_ != SessionState::PLAYING) {
491        CLOGE("InjectEvent failed, not playing.");
492        return ERR_SESSION_STATE_NOT_MATCH;
493    }
494    return CAST_ENGINE_SUCCESS;
495}
496
497int32_t CastSessionImpl::GetDisplayId(std::string &displayId)
498{
499    if (!Permission::CheckPidPermission()) {
500        return ERR_NO_PERMISSION;
501    }
502    CLOGD("GetDisplayId in");
503    return CAST_ENGINE_SUCCESS;
504}
505
506int32_t CastSessionImpl::ResizeVirtualScreen(uint32_t width, uint32_t height)
507{
508    if (!Permission::CheckPidPermission()) {
509        return ERR_NO_PERMISSION;
510    }
511    return CAST_ENGINE_SUCCESS;
512}
513
514void CastSessionImpl::SetLocalDevice(const CastLocalDevice &localDevice)
515{
516    localDevice_ = localDevice;
517}
518
519bool CastSessionImpl::TransferTo(std::shared_ptr<BaseState> state)
520{
521    if (IsAllowTransferState(state->GetStateId())) {
522        CLOGD("Transfer to %{public}s", SESSION_STATE_STRING[static_cast<int>(state->GetStateId())].c_str());
523        TransferState(state);
524        return true;
525    }
526    return false;
527}
528
529int32_t CastSessionImpl::GetSessionProtocolType(ProtocolType &protocolType)
530{
531    CLOGI("GetSessionProtocolType in");
532    std::unique_lock<std::mutex> lock(mutex_);
533    protocolType = property_.protocolType;
534    return CAST_ENGINE_SUCCESS;
535}
536
537void CastSessionImpl::SetSessionProtocolType(ProtocolType protocolType)
538{
539    CLOGI("SetSessionProtocolType in %d old %d", protocolType, property_.protocolType);
540    std::unique_lock<std::mutex> lock(mutex_);
541    property_.protocolType = protocolType;
542    if (protocolType == ProtocolType::CAST_PLUS_STREAM) {
543        setProperty_.notify_all();
544    }
545}
546
547bool CastSessionImpl::Init()
548{
549    CLOGI("Session state: %{public}s", SESSION_STATE_STRING[static_cast<int>(sessionState_)].c_str());
550
551    srand(static_cast<unsigned int >(time(nullptr)));
552    sessionId_ = rand() % (MAX_SESSION_ID + 1);
553    channelManagerListener_ = std::make_shared<ChannelManagerListenerImpl>(this);
554    channelManager_ = std::make_shared<ChannelManager>(sessionId_, channelManagerListener_);
555
556    rtspListener_ = std::make_shared<RtspListenerImpl>(this);
557    rtspControl_ = IRtspController::GetInstance(rtspListener_, property_.protocolType, property_.endType);
558
559    connectManagerListener_ = std::make_shared<ConnectManagerListenerImpl>(this);
560    ConnectionManager::GetInstance().SetSessionListener(connectManagerListener_);
561
562    defaultState_ = std::make_shared<DefaultState>(SessionState::DEFAULT, this, nullptr);
563    disconnectedState_ = std::make_shared<DisconnectedState>(SessionState::DISCONNECTED, this, defaultState_);
564    authingState_ = std::make_shared<AuthingState>(SessionState::AUTHING, this, defaultState_);
565    connectingState_ = std::make_shared<ConnectingState>(SessionState::CONNECTING, this, defaultState_);
566    connectedState_ = std::make_shared<ConnectedState>(SessionState::CONNECTED, this, defaultState_);
567    disconnectingState_ = std::make_shared<DisconnectingState>(SessionState::DISCONNECTING, this, defaultState_);
568    pausedState_ = std::make_shared<PausedState>(SessionState::PAUSED, this, connectedState_);
569    playingState_ = std::make_shared<PlayingState>(SessionState::PLAYING, this, connectedState_);
570    streamState_ = std::make_shared<StreamState>(SessionState::STREAM, this, connectedState_);
571    TransferTo(disconnectedState_);
572
573    return true;
574}
575
576void CastSessionImpl::Stop()
577{
578    CLOGD("Start to stop session");
579    // remove msg connect timeout to prevent waiting too long for the thread to stop
580    RemoveMessage(Message(static_cast<int>(MessageId::MSG_CONNECT_TIMEOUT)));
581    StopSafty(true);
582    ThreadJoin();
583    CLOGD("End to stop session");
584}
585
586void CastSessionImpl::InitRtspParamInfo(std::shared_ptr<CastRemoteDeviceInfo> remoteDeviceInfo)
587{
588    rtspParamInfo_.SetVideoProperty(property_.videoProperty);
589    rtspParamInfo_.SetVersion(CAST_VERSION);
590    rtspParamInfo_.SetSupportVtpOpt((remoteDeviceInfo->remoteDevice.channelType != ChannelType::SOFT_BUS) ?
591        VtpType::VTP_SUPPORT_VIDEO :
592        VtpType::VTP_NOT_SUPPORT_VIDEO);
593    if (property_.protocolType == ProtocolType::CAST_PLUS_MIRROR ||
594        property_.protocolType == ProtocolType::CAST_PLUS_STREAM ||
595        property_.protocolType == ProtocolType::CAST_COOPERATION) {
596        rtspParamInfo_.SetAudioProperty(property_.audioProperty);
597    }
598
599    if (property_.protocolType == ProtocolType::CAST_PLUS_STREAM) {
600        rtspParamInfo_.SetProjectionMode(CastSessionRtsp::ProjectionMode::STREAM);
601    }
602    auto streamManager = CreateStreamPlayerManager();
603    if (streamManager) {
604        rtspParamInfo_.SetPlayerControllerCapability(streamManager->GetStreamPlayerCapability());
605    }
606
607    const auto &remote = remoteDeviceInfo->remoteDevice;
608    DeviceTypeParamInfo param = {
609        .localDeviceType = localDevice_.deviceType,
610        .localDeviceSubtype = localDevice_.subDeviceType,
611        .remoteDeviceType = remote.deviceType,
612        .remoteDeviceSubtype = remote.subDeviceType,
613    };
614    rtspParamInfo_.SetDeviceTypeParamInfo(param);
615    rtspParamInfo_.SetFeatureSet(std::set<int> { ParamInfo::FEATURE_STOP_VTP, ParamInfo::FEATURE_FINE_STYLUS,
616        ParamInfo::FEATURE_SOURCE_MOUSE, ParamInfo::FEATURE_SOURCE_MOUSE_HISTORY,
617        ParamInfo::FEATURE_SEND_EVENT_CHANGE });
618}
619
620std::string CastSessionImpl::GetCurrentRemoteDeviceId()
621{
622    std::lock_guard<std::mutex> lock(mutex_);
623    if (remoteDeviceList_.empty()) {
624        CLOGE("failed, list is empty.");
625        return "";
626    }
627    return remoteDeviceList_.front().remoteDevice.deviceId;
628}
629
630int CastSessionImpl::ProcessConnect(const Message &msg)
631{
632    UpdateRemoteDeviceInfoFromCastDeviceDataManager(msg.strArg_);
633    auto remoteDeviceInfo = FindRemoteDevice(msg.strArg_);
634    if (remoteDeviceInfo == nullptr) {
635        CLOGE("remote device is null");
636        return -1;
637    }
638    InitRtspParamInfo(remoteDeviceInfo);
639    if (!rtspControl_->Start(rtspParamInfo_, remoteDeviceInfo->remoteDevice.sessionKey,
640        remoteDeviceInfo->remoteDevice.sessionKeyLength)) {
641        CLOGE("Rtsp start failed, session state: %{public}s",
642            SESSION_STATE_STRING[static_cast<int>(sessionState_)].c_str());
643        rtspControl_->Action(ActionType::TEARDOWN);
644        return -1;
645    }
646
647    auto &remote = remoteDeviceInfo->remoteDevice;
648    CLOGD("DeviceName = %s, deviceId = %s, sessionId = %{public}d.", remote.deviceName.c_str(), remote.deviceId.c_str(),
649        remoteDeviceInfo->remoteDevice.sessionId);
650
651    auto request = BuildChannelRequest(remote.deviceId, false, ModuleType::RTSP);
652    if (request == nullptr) {
653        CLOGE("Rtsp start failed, session state: %{public}s",
654            SESSION_STATE_STRING[static_cast<int>(sessionState_)].c_str());
655        return -1;
656    }
657
658    auto sceneType = GetBIZSceneType(static_cast<int>(property_.protocolType));
659    ProcessConnectWriteWrap(__func__,
660        property_.protocolType, sceneType, GetAnonymousDeviceID(remote.deviceId));
661
662    int deviceSessionId = channelManager_->CreateChannel(*request, rtspControl_->GetChannelListener());
663    UpdateRemoteDeviceSessionId(remote.deviceId, deviceSessionId);
664    ConnectionManager::GetInstance().SetRTSPPort(deviceSessionId);
665    remote.rtspPort = deviceSessionId;
666    rtspPort_ = deviceSessionId;
667    CLOGD("Out: deviceName = %s, deviceId = %s, sessionId = %{public}d.", remote.deviceName.c_str(),
668        remote.deviceId.c_str(), remoteDeviceInfo->remoteDevice.sessionId);
669    return deviceSessionId;
670}
671
672void CastSessionImpl::SendConsultData(const std::string &deviceId, int port)
673{
674    CLOGI("SendConsultInfo port");
675    ConnectionManager::GetInstance().SendConsultInfo(deviceId, port);
676}
677
678int CastSessionImpl::SetupRemoteControl(const CastInnerRemoteDevice &remote)
679{
680    CLOGD("SetupRemoteControl.");
681    CLOGD("SetupRemoteControl out");
682    return INVALID_PORT;
683}
684
685bool CastSessionImpl::IsVtpUsed(ChannelType type)
686{
687    return (type != ChannelType::SOFT_BUS) && (rtspParamInfo_.GetSupportVtpOpt() != VtpType::VTP_NOT_SUPPORT_VIDEO);
688}
689
690bool CastSessionImpl::IsChannelClient(ChannelType type)
691{
692    if (property_.endType == EndType::CAST_SOURCE) {
693        return IsVtpUsed(type);
694    }
695
696    return !IsVtpUsed(type);
697}
698
699bool CastSessionImpl::IsChannelNeeded(ChannelType type)
700{
701    return (property_.endType != EndType::CAST_SINK) || !IsVtpUsed(type);
702}
703
704std::pair<int, int> CastSessionImpl::GetMediaPort(ChannelType type, int port)
705{
706    if (type != ChannelType::SOFT_BUS) {
707        if (IsChannelClient(type)) {
708            int videoPort = rand() % (MAX_PORT - MIN_PORT + 1) + MIN_PORT;
709            return std::pair<int, int> { videoPort, videoPort + 1 };
710        }
711        return std::pair<int, int> { port, UNNEEDED_PORT };
712    }
713
714    if (!IsChannelClient(type)) {
715        return (property_.protocolType == ProtocolType::CAST_PLUS_MIRROR ||
716            property_.protocolType == ProtocolType::CAST_PLUS_STREAM ||
717            property_.protocolType == ProtocolType::CAST_COOPERATION) ?
718            std::pair<int, int> { INVALID_PORT, INVALID_PORT } :
719            std::pair<int, int> { INVALID_PORT, UNNEEDED_PORT };
720    }
721
722    if (property_.protocolType == ProtocolType::CAST_PLUS_MIRROR ||
723        property_.protocolType == ProtocolType::CAST_PLUS_STREAM ||
724        property_.protocolType == ProtocolType::CAST_COOPERATION) {
725        if (!IsVtpUsed(type)) {
726            // audio port is same as video base on tcp protocol, softbus don't care about the port.
727            return { port, port };
728        }
729
730        int videoPort = static_cast<int>((static_cast<unsigned int>(port) >> SOCKET_PORT_BITS) & SOCKET_PORT_MASK);
731        int audioPort = static_cast<int>(static_cast<unsigned int>(port) & SOCKET_PORT_MASK);
732        return { videoPort, audioPort };
733    }
734    return { port, UNNEEDED_PORT };
735}
736
737std::optional<int> CastSessionImpl::SetupMedia(const CastInnerRemoteDevice &remote, ChannelType type, int ports)
738{
739    return std::nullopt;
740}
741
742bool CastSessionImpl::ProcessSetUp(const Message &msg)
743{
744    CLOGD("Media ports: %d, rc ports: %d id %s", msg.arg1_, msg.arg2_, msg.strArg_.c_str());
745
746    auto deviceInfo = FindRemoteDevice(msg.strArg_);
747    if (deviceInfo == nullptr) {
748        CLOGE("Remote device is null");
749        rtspControl_->Action(ActionType::TEARDOWN);
750        return false;
751    }
752
753    const auto &remote = deviceInfo->remoteDevice;
754    auto channelType = remote.channelType;
755    CLOGD("DeviceName = %s, deviceId = %s, sessionId = %{public}d, channelType = %{public}d.",
756        remote.deviceName.c_str(), remote.deviceId.c_str(), remote.sessionId, channelType);
757    int remoteControlPort = SetupRemoteControl(remote);
758    if (remoteControlPort == INVALID_PORT) {
759        rtspControl_->Action(ActionType::TEARDOWN);
760        return false;
761    }
762
763    int mediaPort = msg.arg1_;
764    auto port = SetupMedia(remote, channelType, mediaPort);
765    if (port == std::nullopt) {
766        rtspControl_->Action(ActionType::TEARDOWN);
767        return false;
768    }
769
770    if (property_.endType == EndType::CAST_SOURCE) {
771        rtspControl_->SetupPort(*port, remoteControlPort, INVALID_PORT);
772    }
773
774    return true;
775}
776
777bool CastSessionImpl::ProcessSetUpSuccess(const Message &msg)
778{
779    int moduleId = msg.arg1_;
780    CLOGD("Module Id:%{public}d, media state:%{public}hhu, remote control state:%{public}hhu, session state:"
781        "%{public}s",
782        moduleId, mediaState_, remoteCtlState_, SESSION_STATE_STRING[static_cast<int>(sessionState_)].c_str());
783
784    if (moduleId == MODULE_ID_MEDIA && mediaState_ == ModuleState::STARTING) {
785        mediaState_ = ModuleState::START_SUCCESS;
786    }
787
788    if (moduleId == MODULE_ID_RC && remoteCtlState_ == ModuleState::STARTING) {
789        remoteCtlState_ = ModuleState::START_SUCCESS;
790    }
791
792    return (mediaState_ == ModuleState::START_SUCCESS) &&
793        (remoteCtlState_ == ModuleState::IDLE || remoteCtlState_ == ModuleState::START_SUCCESS);
794}
795
796bool CastSessionImpl::ProcessPause(const Message &msg)
797{
798    CLOGD("In");
799    rtspControl_->Action(ActionType::PAUSE);
800    return true;
801}
802
803bool CastSessionImpl::ProcessPauseReq(const Message &msg)
804{
805    CLOGD("In");
806    return true;
807}
808
809void CastSessionImpl::MirrorRcvVideoFrame()
810{
811}
812
813bool CastSessionImpl::ProcessPlay(const Message &msg)
814{
815    CLOGD("In");
816    return (rtspControl_->Action(ActionType::PLAY));
817}
818
819bool CastSessionImpl::ProcessPlayReq(const Message &msg)
820{
821    CLOGD("ProcessPlayReq vtp port:%d", msg.arg1_);
822    if (property_.endType == EndType::CAST_SINK) {
823        return true;
824    } else {
825        return true;
826    }
827}
828
829bool CastSessionImpl::ProcessDisconnect(const Message &msg)
830{
831    auto sceneType = GetBIZSceneType(static_cast<int>(property_.protocolType));
832    HiSysEventWriteWrap(__func__, { {"BIZ_SCENE", sceneType},
833        {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_END)},
834        {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::DISCONNECT_END)},
835        {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_SUCCESS)},
836        {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
837        {"TO_CALL_PKG", DSOFTBUS_NAME}, {"LOCAL_SESS_NAME", ""}, {"PEER_SESS_NAME", ""},
838        {"PEER_UDID", ""}});
839
840    CLOGD("In");
841    rtspControl_->Action(ActionType::TEARDOWN);
842    channelManager_->DestroyAllChannels();
843    return true;
844}
845
846bool CastSessionImpl::ProcessError(const Message &msg)
847{
848    CLOGD("In");
849    bool result = ProcessDisconnect(msg);
850    std::lock_guard<std::mutex> lock(mutex_);
851    auto &devices = remoteDeviceList_;
852    for (auto it = devices.begin(); it != devices.end();) {
853        ChangeDeviceStateLocked(DeviceState::DISCONNECTED, it->remoteDevice.deviceId);
854        ConnectionManager::GetInstance().DisconnectDevice(it->remoteDevice.deviceId);
855        devices.erase(it++);
856    }
857
858    return result;
859}
860
861bool CastSessionImpl::ProcessUpdateVideoSize(const Message &msg)
862{
863    return true;
864}
865
866void CastSessionImpl::UpdateScreenInfo(uint64_t screenId, uint16_t width, uint16_t height)
867{
868}
869
870void CastSessionImpl::UpdateDefaultDisplayRotationInfo(int rotation, uint16_t width, uint16_t height)
871{
872}
873
874bool CastSessionImpl::ProcessStateEvent(MessageId msgId, const Message &msg)
875{
876    if (stateProcessor_[msgId] == nullptr) {
877        CLOGE("%{public}s' processor is null", MESSAGE_ID_STRING[msgId].c_str());
878        return false;
879    }
880
881    return (this->*stateProcessor_[msgId])(msg);
882}
883
884bool CheckJsonMemberType(Json::Value rootValue)
885{
886    if (!rootValue.isMember(KEY_BUNDLE_NAME) || !rootValue[KEY_BUNDLE_NAME].isString()) {
887        CLOGE("parse bundle name failed");
888        return false;
889    }
890    if (!rootValue.isMember(KEY_PID) || !rootValue[KEY_PID].isInt()) {
891        CLOGE("parse pid failed");
892        return false;
893    }
894    if (!rootValue.isMember(KEY_APP_MIN_COMPATIBLE_VERSION) ||
895        !rootValue[KEY_APP_MIN_COMPATIBLE_VERSION].isInt()) {
896        CLOGE("parse app min compatible version failed");
897        return false;
898    }
899    if (!rootValue.isMember(KEY_APP_TARGET_VERSION) || !rootValue[KEY_APP_TARGET_VERSION].isInt()) {
900        CLOGE("parse app target version failed");
901        return false;
902    }
903    return true;
904}
905
906bool CastSessionImpl::ProcessSetCastMode(const Message &msg)
907{
908    CastMode mode = static_cast<CastMode>(msg.arg1_);
909    switch (mode) {
910        default:
911            break;
912    }
913
914    return true;
915}
916
917std::shared_ptr<ChannelRequest> CastSessionImpl::BuildChannelRequest(const std::string &remoteDeviceId,
918    bool isSupportVtp, ModuleType moduleType)
919{
920    auto deviceInfo = FindRemoteDevice(remoteDeviceId);
921    if (deviceInfo == nullptr) {
922        CLOGE("Remote device is null");
923        return nullptr;
924    }
925    const auto &remote = deviceInfo->remoteDevice;
926    bool isReceiver = !(property_.endType == EndType::CAST_SOURCE &&
927        (moduleType == ModuleType::VIDEO || moduleType == ModuleType::AUDIO));
928
929    return std::make_shared<ChannelRequest>(moduleType, isReceiver, localDevice_, remote, property_);
930}
931
932std::shared_ptr<CastRemoteDeviceInfo> CastSessionImpl::FindRemoteDevice(const std::string &deviceId)
933{
934    std::lock_guard<std::mutex> lock(mutex_);
935    return FindRemoteDeviceLocked(deviceId);
936}
937
938std::shared_ptr<CastRemoteDeviceInfo> CastSessionImpl::FindRemoteDeviceLocked(const std::string &deviceId)
939{
940    for (auto &deviceInfo : remoteDeviceList_) {
941        if (deviceInfo.remoteDevice.deviceId == deviceId) {
942            return std::make_shared<CastRemoteDeviceInfo>(deviceInfo);
943        }
944    }
945    return nullptr;
946}
947
948void CastSessionImpl::UpdateRemoteDeviceStateLocked(const std::string &deviceId, DeviceState state)
949{
950    for (auto &deviceInfo : remoteDeviceList_) {
951        if (deviceInfo.remoteDevice.deviceId == deviceId) {
952            deviceInfo.deviceState = state;
953            return;
954        }
955    }
956}
957
958void CastSessionImpl::UpdateRemoteDeviceSessionId(const std::string &deviceId, int sessionId)
959{
960    std::lock_guard<std::mutex> lock(mutex_);
961    for (auto &deviceInfo : remoteDeviceList_) {
962        if (deviceInfo.remoteDevice.deviceId == deviceId) {
963            deviceInfo.remoteDevice.sessionId = sessionId;
964            return;
965        }
966    }
967}
968
969void CastSessionImpl::UpdateRemoteDeviceInfoFromCastDeviceDataManager(const std::string &deviceId)
970{
971    std::lock_guard<std::mutex> lock(mutex_);
972    auto remote = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(deviceId);
973    if (remote == std::nullopt) {
974        CLOGE("Get remote device is empty");
975        return;
976    }
977    for (auto &deviceInfo : remoteDeviceList_) {
978        if (deviceInfo.remoteDevice.deviceId == deviceId) {
979            deviceInfo.remoteDevice.channelType = remote->channelType;
980            deviceInfo.remoteDevice.localIp = remote->localIp;
981            deviceInfo.remoteDevice.remoteIp = remote->remoteIp;
982            if (property_.protocolType != ProtocolType::HICAR) {
983                deviceInfo.remoteDevice.ipAddress = remote->remoteIp;
984            }
985            if (memcpy_s(deviceInfo.remoteDevice.sessionKey, remote->sessionKeyLength, remote->sessionKey,
986                remote->sessionKeyLength) != 0) {
987                CLOGE("SessionKey Copy Error!");
988            }
989            deviceInfo.remoteDevice.sessionKeyLength = remote->sessionKeyLength;
990            return;
991        }
992    }
993}
994
995void CastSessionImpl::RemoveRemoteDevice(const std::string &deviceId)
996{
997    std::lock_guard<std::mutex> lock(mutex_);
998    for (auto it = remoteDeviceList_.begin(); it != remoteDeviceList_.end(); it++) {
999        if (it->remoteDevice.deviceId == deviceId) {
1000            CLOGI("Start to remove remote device:%s", deviceId.c_str());
1001            ConnectionManager::GetInstance().DisconnectDevice(deviceId);
1002            remoteDeviceList_.erase(it);
1003            return;
1004        }
1005    }
1006}
1007
1008bool CastSessionImpl::AddRemoteDevice(const CastRemoteDeviceInfo &remoteDeviceInfo)
1009{
1010    const auto &remote = remoteDeviceInfo.remoteDevice;
1011    if (FindRemoteDevice(remote.deviceId) != nullptr) {
1012        CLOGW("Remote device(%s) has existed", remote.deviceName.c_str());
1013        return false;
1014    }
1015    std::lock_guard<std::mutex> lock(mutex_);
1016    remoteDeviceList_.push_back(remoteDeviceInfo);
1017    return true;
1018}
1019
1020// Reserved for 1->N scenarios
1021bool CastSessionImpl::IsAllowTransferState(SessionState desiredState) const
1022{
1023    return true;
1024}
1025
1026void CastSessionImpl::ChangeDeviceState(DeviceState state, const std::string &deviceId, const EventCode eventCode)
1027{
1028    std::lock_guard<std::mutex> lock(mutex_);
1029    ChangeDeviceStateLocked(state, deviceId, eventCode);
1030}
1031
1032void CastSessionImpl::ChangeDeviceStateLocked(DeviceState state, const std::string &deviceId, const EventCode eventCode)
1033{
1034    auto deviceInfo = FindRemoteDeviceLocked(deviceId);
1035    if (!deviceInfo) {
1036        CLOGE("does not exist this device, deviceId = %s.", deviceId.c_str());
1037        return;
1038    }
1039
1040    CLOGD("New state:%{public}s, old state:%{public}s, device id:%s, eventCode:%{public}d",
1041        DEVICE_STATE_STRING[static_cast<int>(state)].c_str(),
1042        DEVICE_STATE_STRING[static_cast<int>(deviceInfo->deviceState)].c_str(),
1043        deviceId.c_str(),
1044        static_cast<int>(eventCode));
1045    if (state == deviceInfo->deviceState) {
1046        return;
1047    }
1048
1049    UpdateRemoteDeviceStateLocked(deviceId, state);
1050
1051    for (const auto &[pid, listener] : listeners_) {
1052        listener->OnDeviceState(DeviceStateInfo { state, deviceId, eventCode });
1053    }
1054}
1055
1056void CastSessionImpl::ReportDeviceStateInfo(DeviceState state, const std::string &deviceId, const EventCode eventCode)
1057{
1058    CLOGI("ReportDeviceStateInfo in.");
1059    auto deviceInfo = FindRemoteDeviceLocked(deviceId);
1060    if (!deviceInfo) {
1061        CLOGE("does not exist this device, deviceId = %s.", deviceId.c_str());
1062        return;
1063    }
1064    for (const auto &[pid, listener] : listeners_) {
1065        listener->OnDeviceState(DeviceStateInfo { state, deviceId, eventCode });
1066    }
1067}
1068
1069void CastSessionImpl::OnSessionEvent(const std::string &deviceId, const EventCode eventCode)
1070{
1071    std::lock_guard<std::mutex> lock(mutex_);
1072    CLOGD("Session event: %{public}d", static_cast<int32_t>(eventCode));
1073    if (static_cast<int32_t>(eventCode) < 0 or eventCode == EventCode::EVT_CANCEL_BY_SOURCE) {
1074        ConnectionManager::GetInstance().UpdateDeviceState(deviceId, RemoteDeviceState::FOUND);
1075        SendCastMessage(Message(MessageId::MSG_DISCONNECT, deviceId, eventCode));
1076    } else {
1077        SendCastMessage(Message(MessageId::MSG_AUTH, deviceId, eventCode));
1078    }
1079}
1080
1081void CastSessionImpl::OnEvent(EventId eventId, const std::string &data)
1082{
1083    std::unique_lock<std::mutex> lock(mutex_);
1084    if (listeners_.empty()) {
1085        CLOGE("OnEvent failed because listeners_ is empty!");
1086        return;
1087    }
1088    for (const auto &[pid, listener] : listeners_) {
1089        listener->OnEvent(eventId, data);
1090    }
1091}
1092
1093bool CastSessionImpl::ProcessTriggerReq(const Message &msg)
1094{
1095    return false;
1096}
1097
1098void CastSessionImpl::ProcessRtspEvent(int moduleId, int event, const std::string &param)
1099{
1100    switch (moduleId) {
1101        case MODULE_ID_CAST_STREAM:
1102            SendCastMessage(Message(MessageId::MSG_STREAM_RECV_ACTION_EVENT_FROM_PEERS, event, param));
1103            break;
1104        case MODULE_ID_CAST_SESSION:
1105            if (event == static_cast<int>(CastSessionRemoteEventId::READY_TO_PLAYING)) {
1106                SendCastMessage(Message(MessageId::MSG_READY_TO_PLAYING));
1107            }
1108            break;
1109        default:
1110            break;
1111    }
1112}
1113
1114bool CastSessionImpl::IsSupportFeature(const std::set<int> &featureSet, int supportFeature)
1115{
1116    return !featureSet.empty() && featureSet.find(supportFeature) != featureSet.end();
1117}
1118
1119bool CastSessionImpl::IsConnected() const
1120{
1121    return sessionState_ == SessionState::PLAYING || sessionState_ == SessionState::PAUSED ||
1122        sessionState_ == SessionState::CONNECTED || sessionState_ == SessionState::STREAM;
1123}
1124
1125bool CastSessionImpl::SendEventChange(int moduleId, int event, const std::string &param)
1126{
1127    CLOGI("Module id %{public}d send event %{public}d", moduleId, event);
1128    if (!IsConnected() || !rtspControl_) {
1129        CLOGE("Send event change fail, state is not ready %{public}hhu", sessionState_);
1130        return false;
1131    }
1132
1133    if (!IsSupportFeature(rtspControl_->GetNegotiatedFeatureSet(), ParamInfo::FEATURE_SEND_EVENT_CHANGE)) {
1134        CLOGE("The feature is not in the feature set.");
1135        return false;
1136    }
1137
1138    return rtspControl_->SendEventChange(moduleId, event, param);
1139}
1140
1141std::shared_ptr<ICastStreamManager> CastSessionImpl::StreamManagerGetter()
1142{
1143    std::lock_guard<std::mutex> lock(streamMutex_);
1144    return streamManager_;
1145}
1146
1147sptr<IMirrorPlayerImpl> CastSessionImpl::MirrorPlayerGetter()
1148{
1149    std::lock_guard<std::mutex> lock(mirrorMutex_);
1150    return mirrorPlayer_;
1151}
1152
1153bool CastSessionImpl::IsStreamMode()
1154{
1155    std::lock_guard<std::mutex> lock(streamMutex_);
1156    return rtspParamInfo_.GetProjectionMode() == CastSessionRtsp::ProjectionMode::STREAM;
1157}
1158
1159std::string CastSessionImpl::GetPlayerControllerCapability()
1160{
1161    std::lock_guard<std::mutex> lock(streamMutex_);
1162    return rtspParamInfo_.GetPlayerControllerCapability();
1163}
1164
1165bool CastSessionImpl::IsSink()
1166{
1167    std::lock_guard<std::mutex> lock(mutex_);
1168    return property_.endType == EndType::CAST_SINK;
1169}
1170
1171int CastSessionImpl::CreateStreamChannel()
1172{
1173    CLOGD("in");
1174    auto request = BuildChannelRequest(GetCurrentRemoteDeviceId(), false, ModuleType::STREAM);
1175    if (request == nullptr) {
1176        CLOGE("build channel request failed");
1177        return INVALID_PORT;
1178    }
1179
1180    const auto streamManager =  StreamManagerGetter();
1181    if (channelManager_ == nullptr || streamManager == nullptr) {
1182        CLOGE("channelManager_ or streamManager is null");
1183        return INVALID_PORT;
1184    }
1185    int port = channelManager_->CreateChannel(*request, streamManager->GetChannelListener());
1186    if (port == INVALID_PORT) {
1187        CLOGE("create stream channel failed");
1188        return INVALID_PORT;
1189    }
1190    if (property_.endType == EndType::CAST_SOURCE) {
1191        SendEventChange(MODULE_ID_CAST_STREAM, ICastStreamManager::MODULE_EVENT_ID_STREAM_CHANNEL,
1192            std::to_string(port));
1193    }
1194    return port;
1195}
1196
1197void CastSessionImpl::SendCastRenderReadyOption(int isReady)
1198{
1199    std::shared_ptr<IRtspController> rtspControl;
1200    {
1201        std::lock_guard<std::mutex> lock(mutex_);
1202        rtspControl = rtspControl_;
1203        if (!IsConnected() || !rtspControl || property_.endType != EndType::CAST_SINK) {
1204            CLOGE("Send render ready failed");
1205            return;
1206        }
1207    }
1208    rtspControl->SendCastRenderReadyOption(isReady);
1209}
1210
1211int32_t CastSessionImpl::NotifyEvent(EventId eventId, std::string &jsonParam)
1212{
1213    if (!Permission::CheckPidPermission()) {
1214        return CAST_ENGINE_ERROR;
1215    }
1216    switch (eventId) {
1217        default:
1218            break;
1219    }
1220    return CAST_ENGINE_SUCCESS;
1221}
1222
1223int32_t CastSessionImpl::SetCastMode(CastMode mode, std::string &jsonParam)
1224{
1225    CLOGD("in, mode = %d, param = %s", static_cast<int>(mode), jsonParam.c_str());
1226    if (!Permission::CheckPidPermission()) {
1227        return ERR_NO_PERMISSION;
1228    }
1229    if (!SendCastMessage(Message(MessageId::MSG_SET_CAST_MODE, static_cast<int>(mode), jsonParam))) {
1230        return CAST_ENGINE_ERROR;
1231    }
1232    return CAST_ENGINE_SUCCESS;
1233}
1234
1235void CastSessionImpl::OnEventInner(sptr<CastSessionImpl> session, EventId eventId, const std::string &jsonParam)
1236{
1237    std::unique_lock<std::mutex> lock(mutex_);
1238    for (const auto &[pid, listener] : session->listeners_) {
1239        listener->OnEvent(eventId, jsonParam);
1240    }
1241}
1242
1243void CastSessionImpl::OnRemoteCtrlEvent(int eventType, const uint8_t *data, uint32_t len)
1244{
1245    std::unique_lock<std::mutex> lock(mutex_);
1246    for (const auto &[pid, listener] : listeners_) {
1247        listener->OnRemoteCtrlEvent(eventType, data, len);
1248    }
1249}
1250} // namespace CastEngineService
1251} // namespace CastEngine
1252} // namespace OHOS
1253