1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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  */
15 
16 #include "wfd_source_scene.h"
17 #include <display_manager.h>
18 #include <unistd.h>
19 #include "common/common_macro.h"
20 #include "common/const_def.h"
21 #include "common/reflect_registration.h"
22 #include "common/sharing_log.h"
23 #include "configuration/include/config.h"
24 #include "extend/magic_enum/magic_enum.hpp"
25 #include "network/socket/socket_utils.h"
26 #include "screen_capture_def.h"
27 #include "utils/utils.h"
28 #include "wfd_session_def.h"
29 
30 namespace OHOS {
31 namespace Sharing {
32 
33 // The most inclination to be a group owner
34 constexpr uint32_t GROUP_OWNER_INTENT_MAX = 15;
35 
OnP2pStateChanged(int32_t state)36 void WfdSourceScene::WfdP2pCallback::OnP2pStateChanged(int32_t state)
37 {
38     SHARING_LOGI("state: %{public}d.", state);
39     auto scene = scene_.lock();
40     if (scene) {
41         switch (static_cast<Wifi::P2pState>(state)) {
42             case Wifi::P2pState::P2P_STATE_NONE:
43                 break;
44             case Wifi::P2pState::P2P_STATE_IDLE:
45                 break;
46             case Wifi::P2pState::P2P_STATE_STARTING:
47                 break;
48             case Wifi::P2pState::P2P_STATE_STARTED:
49                 if (scene->isSourceRunning_) {
50                     scene->WfdP2pStart();
51                 }
52                 break;
53             case Wifi::P2pState::P2P_STATE_CLOSING:
54                 break;
55             case Wifi::P2pState::P2P_STATE_CLOSED:
56                 if (scene->isSourceRunning_) {
57                     scene->isSourceRunning_ = false;
58                     scene->WfdP2pStop();
59                     scene->OnInnerError(0, 0, SharingErrorCode::ERR_NETWORK_ERROR, "NETWORK ERROR, P2P MODULE STOPPED");
60                 }
61                 break;
62             default:
63                 SHARING_LOGI("none process case.");
64                 break;
65         }
66     }
67 }
68 
OnP2pPersistentGroupsChanged(void)69 void WfdSourceScene::WfdP2pCallback::OnP2pPersistentGroupsChanged(void)
70 {
71     SHARING_LOGI("%{public}s.", __FUNCTION__);
72 }
73 
OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice &device)74 void WfdSourceScene::WfdP2pCallback::OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice &device)
75 {
76     SHARING_LOGI("%{public}s.", __FUNCTION__);
77     auto scene = scene_.lock();
78     if (scene == nullptr) {
79         SHARING_LOGW("scene is nullptr.");
80         return;
81     }
82 
83     if (scene->p2pInstance_ == nullptr) {
84         SHARING_LOGW("p2pInstance is nullptr.");
85         return;
86     }
87 
88     Wifi::WifiP2pLinkedInfo info;
89     if (scene->p2pInstance_->QueryP2pLinkedInfo(info)) {
90         SHARING_LOGE("failed to query p2p link info.");
91         return;
92     }
93 
94     Wifi::P2pConnectedState state = info.GetConnectState();
95     SHARING_LOGI("ConnectState: %{public}d.", state);
96     if (state != Wifi::P2pConnectedState::P2P_DISCONNECTED) {
97         return;
98     }
99 
100     if (scene->connDev_ != nullptr) {
101         scene->OnP2pPeerDisconnected(scene->connDev_->mac);
102     }
103 }
104 
OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> &device)105 void WfdSourceScene::WfdP2pCallback::OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> &device)
106 {
107     SHARING_LOGI("%{public}s.", __FUNCTION__);
108     auto scene = scene_.lock();
109     RETURN_IF_NULL(scene);
110 
111     if (!scene->isSourceDiscovering) {
112         SHARING_LOGI("p2p source is not discovering.");
113         return;
114     }
115 
116     SHARING_LOGI("device size: %{public}zu.", device.size());
117     std::vector<WfdCastDeviceInfo> foundedDevices;
118     for (auto itDev : device) {
119         auto status = itDev.GetP2pDeviceStatus();
120         SHARING_LOGI("device name: %{public}s, mac: %{public}s, status: %{public}d.",
121                      GetAnonyString(itDev.GetDeviceName()).c_str(), GetAnonyString(itDev.GetDeviceAddress()).c_str(),
122                      status);
123         if (status == Wifi::P2pDeviceStatus::PDS_AVAILABLE) {
124             std::string subelement;
125             Wifi::WifiP2pWfdInfo wfdInfo(itDev.GetWfdInfo());
126             wfdInfo.GetDeviceInfoElement(subelement);
127             SHARING_LOGI("\tsession available: %{public}d"
128                          "\tdevice info: %{private}s.",
129                          wfdInfo.isSessionAvailable(), subelement.c_str());
130 
131             if (wfdInfo.isSessionAvailable()) {
132                 WfdCastDeviceInfo deviceInfo;
133                 deviceInfo.deviceId = itDev.GetDeviceAddress();
134                 deviceInfo.deviceName = itDev.GetDeviceName();
135                 deviceInfo.primaryDeviceType = itDev.GetPrimaryDeviceType();
136                 deviceInfo.secondaryDeviceType = itDev.GetSecondaryDeviceType();
137 
138                 foundedDevices.emplace_back(deviceInfo);
139             }
140         }
141     }
142 
143     if (!foundedDevices.empty()) {
144         scene->OnDeviceFound(foundedDevices);
145     }
146 }
147 
OnP2pPrivatePeersChanged(const std::string &priWfdInfo)148 void WfdSourceScene::WfdP2pCallback::OnP2pPrivatePeersChanged(const std::string &priWfdInfo)
149 {
150     SHARING_LOGI("%{public}s.", __FUNCTION__);
151 }
152 
OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> &srvInfo)153 void WfdSourceScene::WfdP2pCallback::OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> &srvInfo)
154 {
155     SHARING_LOGI("%{public}s.", __FUNCTION__);
156 }
157 
OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo &info)158 void WfdSourceScene::WfdP2pCallback::OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo &info)
159 {
160     Wifi::P2pConnectedState state = info.GetConnectState();
161     SHARING_LOGI("OnP2pConnectionChanged ConnectState: %{public}d.", state);
162 
163     auto scene = scene_.lock();
164     if (scene == nullptr || scene->p2pInstance_ == nullptr) {
165         SHARING_LOGW("scene is nullptr.");
166         return;
167     }
168 
169     if (state != Wifi::P2pConnectedState::P2P_CONNECTED) {
170         scene->p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_DISCONNECT_DEVICE);
171         return;
172     }
173     scene->p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_CONNECT_DEVICE);
174     SHARING_LOGD("goip: %{private}s.", GetAnonyString(info.GetGroupOwnerAddress()).c_str());
175     if (info.GetGroupOwnerAddress() == "") {
176         return;
177     }
178 
179     Wifi::WifiP2pGroupInfo group;
180     if (Wifi::ErrCode::WIFI_OPT_SUCCESS != scene->p2pInstance_->GetCurrentGroup(group)) {
181         SHARING_LOGE("GetCurrentGroup failed");
182         return;
183     }
184 
185     Wifi::WifiP2pDevice goDevice = group.GetOwner();
186 
187     ConnectionInfo connectionInfo;
188     connectionInfo.ip = info.GetGroupOwnerAddress();
189     connectionInfo.mac = goDevice.GetDeviceAddress();
190     connectionInfo.deviceName = goDevice.GetDeviceName();
191     connectionInfo.primaryDeviceType = goDevice.GetPrimaryDeviceType();
192     connectionInfo.secondaryDeviceType = goDevice.GetSecondaryDeviceType();
193     connectionInfo.ctrlPort = goDevice.GetWfdInfo().GetCtrlPort();
194     connectionInfo.state = ConnectionState::CONNECTED;
195 
196     SHARING_LOGD("device connected, mac: %{private}s, ip: %{private}s, port: %{private}d.",
197                  GetAnonyString(connectionInfo.mac).c_str(), GetAnonyString(connectionInfo.ip).c_str(),
198                  connectionInfo.ctrlPort);
199     scene->OnP2pPeerConnected(connectionInfo);
200 }
201 
OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo &info)202 void WfdSourceScene::WfdP2pCallback::OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo &info)
203 {
204     SHARING_LOGD("trace.");
205 }
206 
OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo &info)207 void WfdSourceScene::WfdP2pCallback::OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo &info)
208 {
209     SHARING_LOGD("trace.");
210 }
211 
OnP2pDiscoveryChanged(bool isChange)212 void WfdSourceScene::WfdP2pCallback::OnP2pDiscoveryChanged(bool isChange)
213 {
214     SHARING_LOGD("isChange: %{public}d.", isChange);
215 }
216 
OnP2pActionResult(Wifi::P2pActionCallback action, Wifi::ErrCode code)217 void WfdSourceScene::WfdP2pCallback::OnP2pActionResult(Wifi::P2pActionCallback action, Wifi::ErrCode code)
218 {
219     SHARING_LOGD("action: %{public}hhu, code: %{public}d.", action, code);
220 }
221 
OnConfigChanged(Wifi::CfgType type, char *data, int32_t dataLen)222 void WfdSourceScene::WfdP2pCallback::OnConfigChanged(Wifi::CfgType type, char *data, int32_t dataLen)
223 {
224     (void)type;
225     (void)data;
226     (void)dataLen;
227     SHARING_LOGI("%{public}s.", __FUNCTION__);
228 }
229 
WfdSourceScene()230 WfdSourceScene::WfdSourceScene()
231 {
232     SHARING_LOGD("id: %{public}u.", GetId());
233     p2pSysEvent_ = std::make_shared<SharingHiSysEvent>(BIZSceneType::P2P_START_DISCOVERY, P2P_PKG);
234 }
235 
~WfdSourceScene()236 WfdSourceScene::~WfdSourceScene()
237 {
238     SHARING_LOGD("id: %{public}u.", GetId());
239     Release();
240 }
241 
OnCheckWfdConnection()242 void WfdSourceScene::OnCheckWfdConnection()
243 {
244     ResetCheckWfdConnectionTimer();
245     OnInnerError(0, 0, SharingErrorCode::ERR_CONNECTION_TIMEOUT, "wfd connection timeout");
246 }
247 
SetCheckWfdConnectionTimer()248 void WfdSourceScene::SetCheckWfdConnectionTimer()
249 {
250     int32_t interval = P2P_CONNECT_TIMEOUT * WFD_SEC_TO_MSEC;
251     if (timer_ != nullptr) {
252         timerId_ = timer_->Register(std::bind(&WfdSourceScene::OnCheckWfdConnection, this), interval);
253         timer_->Setup();
254     }
255 }
256 
ResetCheckWfdConnectionTimer()257 void WfdSourceScene::ResetCheckWfdConnectionTimer()
258 {
259     if (timer_ != nullptr && timerId_ != 0) {
260         timer_->Unregister(timerId_);
261         timerId_ = 0;
262     }
263 }
264 
Initialize()265 void WfdSourceScene::Initialize()
266 {
267     SHARING_LOGI("%{public}s.", __FUNCTION__);
268     SharingValue::Ptr values = nullptr;
269 
270     auto ret = Config::GetInstance().GetConfig("khSharingWfd", "ctrlport", "defaultWfdCtrlport", values);
271     if (ret == CONFIGURE_ERROR_NONE) {
272         values->GetValue<int32_t>(ctrlPort_);
273     }
274 
275     ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "videoCodec", values);
276     if (ret == CONFIGURE_ERROR_NONE) {
277         int32_t videoCodec;
278         values->GetValue<int32_t>(videoCodec);
279         videoCodecId_ = static_cast<CodecId>(videoCodec);
280         videoCodecId_ = CodecId::CODEC_H264;
281     }
282 
283     ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "videoFormat", values);
284     if (ret == CONFIGURE_ERROR_NONE) {
285         int32_t videoFormat;
286         values->GetValue<int32_t>(videoFormat);
287         videoFormat_ = static_cast<VideoFormat>(videoFormat);
288         videoFormat_ = VideoFormat::VIDEO_1920X1080_25;
289     }
290 
291     ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "audioCodec", values);
292     if (ret == CONFIGURE_ERROR_NONE) {
293         int32_t audioCodec;
294         values->GetValue<int32_t>(audioCodec);
295         audioCodecId_ = static_cast<CodecId>(audioCodec);
296         audioCodecId_ = CodecId::CODEC_AAC;
297     }
298 
299     ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "audioFormat", values);
300     if (ret == CONFIGURE_ERROR_NONE) {
301         int32_t audioFormat;
302         values->GetValue<int32_t>(audioFormat);
303         audioFormat_ = static_cast<AudioFormat>(audioFormat);
304         audioFormat_ = AudioFormat::AUDIO_48000_16_2;
305     }
306 
307     p2pInstance_ = Wifi::WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
308     RETURN_IF_NULL(p2pInstance_);
309     if (shared_from_this() == nullptr) {
310         SHARING_LOGE("trace*********************WfdSourceScene NULL.");
311     }
312 
313     sptr<WfdP2pCallback> wfdP2pCallback(new WfdP2pCallback(shared_from_this()));
314 
315     std::vector<std::string> event = {EVENT_P2P_PEER_DEVICE_CHANGE, EVENT_P2P_DEVICE_STATE_CHANGE,
316                                       EVENT_P2P_CONN_STATE_CHANGE,  EVENT_P2P_STATE_CHANGE,
317                                       EVENT_P2P_SERVICES_CHANGE,    EVENT_P2P_DISCOVERY_CHANGE};
318     p2pInstance_->RegisterCallBack(wfdP2pCallback, event);
319 }
320 
Release()321 void WfdSourceScene::Release()
322 {
323     SHARING_LOGI("%{public}s.", __FUNCTION__);
324     if (timer_ != nullptr) {
325         timer_->Shutdown();
326         timer_.reset();
327     }
328     auto sharingAdapter = sharingAdapter_.lock();
329     if (sharingAdapter != nullptr) {
330         std::lock_guard<std::mutex> lock(mutex_);
331         if ((connDev_ != nullptr) && (connDev_->contextId != INVALID_ID) && (connDev_->agentId != INVALID_ID)) {
332             auto sessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
333             sessionMsg->type = EVENT_SESSION_TEARDOWN;
334             sessionMsg->toMgr = MODULE_CONTEXT;
335             sessionMsg->dstId = connDev_->contextId;
336             sessionMsg->agentId = connDev_->agentId;
337 
338             SharingEvent event;
339             event.eventMsg = std::move(sessionMsg);
340             sharingAdapter->ForwardEvent(connDev_->contextId, connDev_->agentId, event, true);
341             sharingAdapter->DestroyAgent(connDev_->contextId, connDev_->agentId);
342             if ((contextId_ != INVALID_ID) && (agentId_ != INVALID_ID)) {
343                 sharingAdapter->DestroyAgent(contextId_, agentId_);
344             }
345         }
346     }
347 
348     if (p2pInstance_) {
349         p2pInstance_->RemoveGroup();
350     }
351     p2pInstance_.reset();
352 }
353 
OnDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)354 void WfdSourceScene::OnDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)
355 {
356     SHARING_LOGI("%{public}s.", __FUNCTION__);
357 }
358 
OnRequest(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)359 void WfdSourceScene::OnRequest(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)
360 {
361     RETURN_IF_NULL(msg);
362     switch (msg->GetMsgId()) {
363         case WfdSourceStartDiscoveryReq::MSG_ID: {
364             auto rsp = std::make_shared<WfdCommonRsp>();
365 
366             rsp->ret = HandleStartDiscovery(msg, rsp);
367             reply = std::static_pointer_cast<BaseMsg>(rsp);
368             break;
369         }
370         case WfdSourceStopDiscoveryReq::MSG_ID: {
371             auto rsp = std::make_shared<WfdCommonRsp>();
372 
373             rsp->ret = HandleStopDiscovery(msg, rsp);
374             reply = std::static_pointer_cast<BaseMsg>(rsp);
375             break;
376         }
377         case WfdSourceAddDeviceReq::MSG_ID: {
378             ResetCheckWfdConnectionTimer();
379             auto rsp = std::make_shared<WfdCommonRsp>();
380             rsp->ret = WfdSourceScene::HandleAddDevice(msg, rsp);
381             SetCheckWfdConnectionTimer();
382             reply = std::static_pointer_cast<BaseMsg>(rsp);
383             break;
384         }
385         case WfdSourceRemoveDeviceReq::MSG_ID: {
386             auto rsp = std::make_shared<WfdCommonRsp>();
387 
388             rsp->ret = HandleRemoveDevice(msg, rsp);
389             reply = std::static_pointer_cast<BaseMsg>(rsp);
390             break;
391         }
392         case DestroyScreenCaptureReq::MSG_ID: {
393             auto data = std::static_pointer_cast<DestroyScreenCaptureReq>(msg);
394             auto rsp = std::make_shared<WfdCommonRsp>();
395             rsp->ret = HandleDestroyScreenCapture(data);
396             reply = std::static_pointer_cast<BaseMsg>(rsp);
397             break;
398         }
399         default:
400             SHARING_LOGW("unknown msg request.");
401             break;
402     }
403 }
404 
HandleStartDiscovery(std::shared_ptr<BaseMsg> &baseMsg, std::shared_ptr<WfdCommonRsp> &reply)405 int32_t WfdSourceScene::HandleStartDiscovery(std::shared_ptr<BaseMsg> &baseMsg,
406                                              std::shared_ptr<WfdCommonRsp> &reply)
407 {
408     SHARING_LOGI("%{public}s.", __FUNCTION__);
409     (void)baseMsg;
410     (void)reply;
411     int32_t ret = 0;
412     if (p2pInstance_ == nullptr) {
413         SHARING_LOGW("p2pInstance is nullptr.");
414         return -1;
415     }
416     if (!isSourceRunning_) {
417         p2pSysEvent_->ReportStart(__func__, BIZSceneStage::P2P_START_DISCOVERY);
418         int32_t status = 0;
419         p2pInstance_->GetP2pEnableStatus(status);
420         switch (static_cast<Wifi::P2pState>(status)) {
421             case Wifi::P2pState::P2P_STATE_NONE:     // fall-through
422             case Wifi::P2pState::P2P_STATE_IDLE:     // fall-through
423             case Wifi::P2pState::P2P_STATE_STARTING: // fall-through
424             case Wifi::P2pState::P2P_STATE_CLOSING: {
425                 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "HandleStart current p2p state: CLOSING");
426                 ret = -1;
427                 break;
428             }
429             case Wifi::P2pState::P2P_STATE_STARTED: {
430                 isSourceRunning_ = true;
431                 WfdP2pStart();
432                 break;
433             }
434             case Wifi::P2pState::P2P_STATE_CLOSED: {
435                 isSourceRunning_ = true;
436                 p2pInstance_->EnableP2p();
437                 break;
438             }
439             default: {
440                 SHARING_LOGI("none process case.");
441                 break;
442             }
443         }
444     }
445     if (ret == 0) {
446         ret = p2pInstance_->DiscoverDevices();
447         isSourceDiscovering = true;
448     } else {
449         p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_START_DISCOVERY, BlzErrorCode::ERROR_FAIL);
450     }
451     return ret;
452 }
453 
HandleStopDiscovery(std::shared_ptr<BaseMsg> &baseMsg, std::shared_ptr<WfdCommonRsp> &reply)454 int32_t WfdSourceScene::HandleStopDiscovery(std::shared_ptr<BaseMsg> &baseMsg,
455                                             std::shared_ptr<WfdCommonRsp> &reply)
456 {
457     SHARING_LOGI("%{public}s.", __FUNCTION__);
458     (void)baseMsg;
459     (void)reply;
460     if (!isSourceRunning_) {
461         SHARING_LOGW("p2p source is not running.");
462         return -1;
463     }
464 
465     if (p2pInstance_ == nullptr) {
466         SHARING_LOGW("p2pInstance is nullptr.");
467         return -1;
468     }
469 
470     int32_t ret = p2pInstance_->StopDiscoverDevices();
471     isSourceDiscovering = false;
472     return ret;
473 }
474 
HandleAddDevice(std::shared_ptr<BaseMsg> &baseMsg, std::shared_ptr<WfdCommonRsp> &reply)475 int32_t WfdSourceScene::HandleAddDevice(std::shared_ptr<BaseMsg> &baseMsg,
476                                         std::shared_ptr<WfdCommonRsp> &reply)
477 {
478     SHARING_LOGI("%{public}s.", __FUNCTION__);
479     (void)reply;
480     if (!isSourceRunning_ || p2pInstance_ == nullptr) {
481         SHARING_LOGW("p2p source is not running.");
482         return -1;
483     }
484 
485     std::shared_ptr<WfdSourceAddDeviceReq> msg = std::static_pointer_cast<WfdSourceAddDeviceReq>(baseMsg);
486     auto displayIds = OHOS::Rosen::DisplayManager::GetInstance().GetAllDisplayIds();
487     bool findDisplayId = false;
488     for (auto displayId : displayIds) {
489         SHARING_LOGD("displayId = %{public}" PRIu64, displayId);
490         if (msg->screenId == displayId) {
491             findDisplayId = true;
492             break;
493         }
494     }
495     if (!findDisplayId) {
496         SHARING_LOGE("can't find screenId %{public}" PRIu64, msg->screenId);
497         return ERR_BAD_PARAMETER;
498     }
499     p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_DEVICE_FOUND);
500     p2pSysEvent_->ChangeScene(BIZSceneType::P2P_CONNECT_DEVICE);
501     p2pSysEvent_->ReportStart(__func__, BIZSceneStage::P2P_CONNECT_DEVICE);
502     Wifi::WifiP2pConfig config;
503     config.SetDeviceAddress(msg->deviceId);
504     config.SetDeviceAddressType(OHOS::Wifi::RANDOM_DEVICE_ADDRESS);
505     config.SetGroupOwnerIntent(GROUP_OWNER_INTENT_MAX - 1);
506 
507     screenId_ = msg->screenId;
508     int32_t ret = p2pInstance_->P2pConnect(config);
509     SHARING_LOGE("connect device: %{public}s, ret = %{public}d", GetAnonyString(msg->deviceId).c_str(), ret);
510     return ret;
511 }
512 
HandleRemoveDevice(std::shared_ptr<BaseMsg> &baseMsg, std::shared_ptr<WfdCommonRsp> &reply)513 int32_t WfdSourceScene::HandleRemoveDevice(std::shared_ptr<BaseMsg> &baseMsg,
514                                            std::shared_ptr<WfdCommonRsp> &reply)
515 {
516     SHARING_LOGI("%{public}s.", __FUNCTION__);
517     (void)reply;
518     auto sharingAdapter = sharingAdapter_.lock();
519     RETURN_INVALID_IF_NULL(sharingAdapter);
520 
521     std::shared_ptr<WfdSourceRemoveDeviceReq> msg = std::static_pointer_cast<WfdSourceRemoveDeviceReq>(baseMsg);
522 
523     std::lock_guard<std::mutex> lock(mutex_);
524     if ((connDev_ == nullptr) || (connDev_->mac != msg->deviceId) || connDev_->state != ConnectionState::CONNECTED) {
525         SHARING_LOGE("can not find dev, deviceId: %{public}s.", GetAnonyString(msg->deviceId).c_str());
526         return -1;
527     }
528     auto sessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
529     sessionMsg->type = EVENT_SESSION_TEARDOWN;
530     sessionMsg->toMgr = MODULE_CONTEXT;
531     sessionMsg->dstId = connDev_->contextId;
532     sessionMsg->agentId = connDev_->agentId;
533 
534     SharingEvent event;
535     event.eventMsg = std::move(sessionMsg);
536     sharingAdapter->ForwardEvent(connDev_->contextId, connDev_->agentId, event, true);
537 
538     connDev_.reset();
539     int ret = sharingAdapter->DestroyAgent(contextId_, agentId_);
540     if (p2pInstance_) {
541         p2pSysEvent_->ChangeScene(BIZSceneType::P2P_DISCONNECT_DEVICE);
542         p2pSysEvent_->ReportStart(__func__, BIZSceneStage::P2P_DISCONNECT_DEVICE);
543         p2pInstance_->RemoveGroup();
544     }
545     return ret;
546 }
547 
CreateScreenCapture()548 int32_t WfdSourceScene::CreateScreenCapture()
549 {
550     SHARING_LOGI("%{public}s.", __FUNCTION__);
551     auto sharingAdapter = sharingAdapter_.lock();
552     if (sharingAdapter != nullptr) {
553         std::unique_lock<std::mutex> lock(mutex_);
554 
555         sharingAdapter->CreateAgent(contextId_, agentId_, AgentType::SINK_AGENT, "ScreenCaptureSession");
556         if (contextId_ == INVALID_ID || agentId_ == INVALID_ID) {
557             lock.unlock();
558             SHARING_LOGE("Create ScreenCapture sink agent failed");
559             return ERR_AGENT_CREATE;
560         } else {
561             SHARING_LOGI("Create ScreenCapture sink agent, contextId: %{public}u, agentId: %{public}u", contextId_,
562                          agentId_);
563         }
564 
565         auto startSessionMsg = std::make_shared<ScreenCaptureSessionEventMsg>();
566         startSessionMsg->mediaType = MEDIA_TYPE_AV;
567         startSessionMsg->type = EVENT_SESSION_INIT;
568         startSessionMsg->toMgr = MODULE_CONTEXT;
569         startSessionMsg->dstId = contextId_;
570         startSessionMsg->agentId = agentId_;
571         startSessionMsg->screenId = screenId_;
572         videoFormat_ = VideoFormat::VIDEO_1920X1080_25;
573 
574         startSessionMsg->videoFormat = videoFormat_;
575         startSessionMsg->audioFormat = audioFormat_;
576 
577         SharingEvent event;
578         event.eventMsg = std::move(startSessionMsg);
579 
580         sharingAdapter->ForwardEvent(contextId_, agentId_, event, true);
581         sharingAdapter->Start(contextId_, agentId_);
582     }
583 
584     return ERR_OK;
585 }
586 
HandleDestroyScreenCapture(std::shared_ptr<DestroyScreenCaptureReq> &msg)587 int32_t WfdSourceScene::HandleDestroyScreenCapture(std::shared_ptr<DestroyScreenCaptureReq> &msg)
588 {
589     SHARING_LOGI("%{public}s.", __FUNCTION__);
590     (void)msg;
591     auto sharingAdapter = sharingAdapter_.lock();
592     if (sharingAdapter != nullptr) {
593         sharingAdapter->DestroyAgent(contextId_, agentId_);
594     }
595     return ERR_OK;
596 }
597 
AppendCast(const std::string &deviceId)598 int32_t WfdSourceScene::AppendCast(const std::string &deviceId)
599 {
600     SHARING_LOGI("%{public}s.", __FUNCTION__);
601     auto sharingAdapter = sharingAdapter_.lock();
602     RETURN_INVALID_IF_NULL(sharingAdapter);
603 
604     std::unique_lock<std::mutex> lock(mutex_);
605     if ((connDev_ == nullptr) || (connDev_->mac != deviceId)) {
606         SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(deviceId).c_str());
607         OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "AppendCast can't find the dev");
608         return -1;
609     }
610     auto port = SocketUtils::GetAvailableUdpPortPair();
611     if (port == 0) {
612         SHARING_LOGE("get udp port failed.");
613         return -1;
614     }
615 
616     uint32_t contextId = contextId_;
617     uint32_t agentId = agentId_;
618     sharingAdapter->CreateAgent(contextId, agentId, AgentType::SRC_AGENT, "WfdSourceSession");
619     if (contextId == INVALID_ID || agentId == INVALID_ID) {
620         lock.unlock();
621         SHARING_LOGE("create source agent failed.");
622         return -1;
623     }
624     SHARING_LOGI("create source agent, contextId: %{public}u, agentId: %{public}u", contextId, agentId);
625     connDev_->contextId = contextId;
626     connDev_->agentId = agentId;
627 
628     if (connDev_->isRunning == true) {
629         return 0;
630     }
631     connDev_->isRunning = true;
632 
633     auto startSessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
634     startSessionMsg->type = EVENT_SESSION_INIT;
635     startSessionMsg->sinkAgentId = agentId_;
636     startSessionMsg->toMgr = MODULE_CONTEXT;
637     startSessionMsg->dstId = contextId;
638     startSessionMsg->agentId = agentId;
639     startSessionMsg->ip = connDev_->ip;
640     startSessionMsg->mac = connDev_->mac;
641     startSessionMsg->remotePort = connDev_->ctrlPort;
642     startSessionMsg->videoFormat = connDev_->videoFormatId;
643     startSessionMsg->audioFormat = connDev_->audioFormatId;
644     startSessionMsg->localPort = port;
645 
646     SharingEvent event;
647     event.eventMsg = std::move(startSessionMsg);
648     sharingAdapter->ForwardEvent(contextId, agentId, event, true);
649     sharingAdapter->Start(contextId, agentId);
650 
651     return 0;
652 }
653 
WfdP2pStart()654 void WfdSourceScene::WfdP2pStart()
655 {
656     SHARING_LOGI("%{public}s.", __FUNCTION__);
657     if (p2pInstance_) {
658         p2pInstance_->RemoveGroup();
659 
660         Wifi::WifiP2pWfdInfo wfdInfo;
661         wfdInfo.SetWfdEnabled(true);
662         wfdInfo.SetDeviceInfo(0x10);
663         wfdInfo.SetCtrlPort(ctrlPort_);
664         wfdInfo.SetMaxThroughput(0x00c8);
665 
666         p2pInstance_->SetP2pWfdInfo(wfdInfo);
667 
668         SHARING_LOGD("WfdSourceScene DiscoverDevices.");
669         p2pInstance_->DiscoverDevices();
670         isSourceDiscovering = true;
671     }
672 }
673 
WfdP2pStop()674 void WfdSourceScene::WfdP2pStop()
675 {
676     SHARING_LOGI("%{public}s.", __FUNCTION__);
677     auto sharingAdapter = sharingAdapter_.lock();
678     if (sharingAdapter != nullptr) {
679         std::lock_guard<std::mutex> lock(mutex_);
680         if ((connDev_ != nullptr) && (connDev_->contextId != INVALID_ID) && (connDev_->agentId != INVALID_ID)) {
681             auto sessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
682             sessionMsg->type = EVENT_SESSION_TEARDOWN;
683             sessionMsg->toMgr = MODULE_CONTEXT;
684             sessionMsg->dstId = connDev_->contextId;
685             sessionMsg->agentId = connDev_->agentId;
686             SharingEvent event;
687             event.eventMsg = std::move(sessionMsg);
688             sharingAdapter->ForwardEvent(connDev_->contextId, connDev_->agentId, event, true);
689         }
690 
691         if ((contextId_ != INVALID_ID) && (agentId_ != INVALID_ID)) {
692             sharingAdapter->DestroyAgent(contextId_, agentId_);
693         }
694     }
695 
696     if (p2pInstance_) {
697         p2pInstance_->RemoveGroup();
698     }
699 }
700 
OnDeviceFound(const std::vector<WfdCastDeviceInfo> &deviceInfos)701 void WfdSourceScene::OnDeviceFound(const std::vector<WfdCastDeviceInfo> &deviceInfos)
702 {
703     SHARING_LOGI("%{public}s.", __FUNCTION__);
704     auto ipcAdapter = ipcAdapter_.lock();
705     RETURN_IF_NULL(ipcAdapter);
706     auto msg = std::make_shared<WfdSourceDeviceFoundMsg>();
707     msg->deviceInfos = deviceInfos;
708     if (p2pSysEvent_->GetScene() == static_cast<int>(BIZSceneType::P2P_START_DISCOVERY)) {
709         for (auto &deviceInfo : deviceInfos) {
710             p2pSysEvent_->Report(__func__, BIZSceneStage::P2P_DEVICE_FOUND, StageResType::STAGE_RES_SUCCESS,
711                                  GetAnonyString(deviceInfo.deviceId));
712         }
713     }
714 
715     auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
716     ipcAdapter->SendRequest(msg, reply);
717 }
718 
OnP2pPeerConnected(ConnectionInfo &connectionInfo)719 void WfdSourceScene::OnP2pPeerConnected(ConnectionInfo &connectionInfo)
720 {
721     SHARING_LOGE("OnP2pPeerConnected, deviceName: %{public}s, mac: %{public}s, ip: %{public}s, port: %{public}d.",
722                  GetAnonyString(connectionInfo.deviceName).c_str(), GetAnonyString(connectionInfo.mac).c_str(),
723                  GetAnonyString(connectionInfo.ip).c_str(), connectionInfo.ctrlPort);
724 
725     if (!isSourceRunning_) {
726         SHARING_LOGW("source service is not running.");
727         return;
728     }
729 
730     auto sharingAdapter = sharingAdapter_.lock();
731     if (sharingAdapter != nullptr) {
732         std::lock_guard<std::mutex> lock(mutex_);
733         if ((connDev_ != nullptr) && (connDev_->mac == connectionInfo.mac)) {
734             SHARING_LOGW("devcie is alerady connected, mac: %s.", GetAnonyString(connectionInfo.mac).c_str());
735             return;
736         }
737         connectionInfo.videoCodecId = videoCodecId_;
738         connectionInfo.videoFormatId = videoFormat_;
739         connectionInfo.audioCodecId = audioCodecId_;
740         connectionInfo.audioFormatId = audioFormat_;
741 
742         connDev_ = std::make_unique<ConnectionInfo>(connectionInfo);
743         SHARING_LOGI("connected, devMac: %s, devIp: %s.", GetAnonyString(connectionInfo.mac).c_str(),
744                      GetAnonyString(connectionInfo.ip).c_str());
745     }
746 
747     OnConnectionChanged(connectionInfo);
748 }
749 
OnP2pPeerDisconnected(ConnectionInfo &connectionInfo)750 void WfdSourceScene::OnP2pPeerDisconnected(ConnectionInfo &connectionInfo)
751 {
752     SHARING_LOGI("%{public}s.", __FUNCTION__);
753     OnP2pPeerDisconnected(connectionInfo.mac);
754 }
755 
OnP2pPeerDisconnected(const std::string &mac)756 void WfdSourceScene::OnP2pPeerDisconnected(const std::string &mac)
757 {
758     SHARING_LOGI("%{public}s.", __FUNCTION__);
759     {
760         std::lock_guard<std::mutex> lock(mutex_);
761         if ((connDev_ == nullptr) || (connDev_->mac != mac)) {
762             SHARING_LOGW("can not find dev, mac: %s.", GetAnonyString(mac).c_str());
763             return;
764         }
765         connDev_->state = ConnectionState::DISCONNECTED;
766         OnConnectionChanged(*connDev_);
767         connDev_.reset();
768     }
769 
770     if ((contextId_ == INVALID_ID) || (agentId_ == INVALID_ID)) {
771         return;
772     }
773 
774     auto sharingAdapter = sharingAdapter_.lock();
775     if (sharingAdapter != nullptr) {
776         sharingAdapter->DestroyAgent(contextId_, agentId_);
777     }
778 
779     if (p2pInstance_) {
780         p2pInstance_->RemoveGroup();
781     }
782 }
783 
ErrorCodeFiltering(int32_t &code)784 void WfdSourceScene::ErrorCodeFiltering(int32_t &code)
785 {
786     SHARING_LOGD("the error code is %{public}d.", code);
787     switch (ABSTRACT_ERR_BASE(code)) {
788         case SharingErrorCode::ERR_CONTEXT_AGENT_BASE: // fall-through
789         case SharingErrorCode::ERR_SESSION_BASE:
790             code = SharingErrorCode::ERR_GENERAL_ERROR;
791             SHARING_LOGD("the error change to %{public}d.", code);
792             break;
793         case SharingErrorCode::ERR_PROSUMER_BASE: {
794             switch (code) {
795                 case ERR_PROSUMER_START:
796                     code = SharingErrorCode::ERR_CONNECTION_FAILURE;
797                     break;
798                 case ERR_PROSUMER_TIMEOUT:
799                     code = SharingErrorCode::ERR_CONNECTION_TIMEOUT;
800                     break;
801                 case ERR_PROSUMER_DESTROY:
802                     code = SharingErrorCode::ERR_STATE_EXCEPTION;
803                     break;
804                 default:
805                     code = SharingErrorCode::ERR_GENERAL_ERROR;
806                     break;
807             }
808             break;
809         }
810         default:
811             SHARING_LOGI("none process case.");
812             break;
813     }
814 }
815 
OnInnerError(uint32_t contextId, uint32_t agentId, SharingErrorCode errorCode, std::string message)816 void WfdSourceScene::OnInnerError(uint32_t contextId, uint32_t agentId, SharingErrorCode errorCode, std::string message)
817 {
818     SHARING_LOGI("%{public}s.", __FUNCTION__);
819     auto ipcAdapter = ipcAdapter_.lock();
820     RETURN_IF_NULL(ipcAdapter);
821 
822     auto msg = std::make_shared<WfdErrorMsg>();
823     msg->contextId = contextId;
824     msg->agentId = agentId;
825     msg->errorCode = errorCode;
826 
827     if (errorCode == SharingErrorCode::ERR_PROSUMER_TIMEOUT) {
828         msg->message =
829             "contextId: " + std::to_string(contextId) + ", agentId: " + std::to_string(agentId) + ", producer timeout";
830     } else {
831         msg->message = std::move(message);
832     }
833 
834     ErrorCodeFiltering(msg->errorCode);
835     auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
836 
837     SHARING_LOGW("receive errorCode: %{public}d.", errorCode);
838     ipcAdapter->SendRequest(msg, reply);
839 }
840 
OnInnerDestroy(uint32_t contextId, uint32_t agentId, AgentType agentType)841 void WfdSourceScene::OnInnerDestroy(uint32_t contextId, uint32_t agentId, AgentType agentType)
842 {
843     SHARING_LOGI("HandleInnerDestroy, contextId: %{public}u, agentId: %{public}u, agentType: %{public}s.", contextId,
844                  agentId, std::string(magic_enum::enum_name(agentType)).c_str());
845     std::lock_guard<std::mutex> lock(mutex_);
846     if (connDev_ == nullptr) {
847         SHARING_LOGE("connDev_ is nullptr.");
848         return;
849     }
850 
851     if ((contextId == connDev_->contextId) && ((agentId == connDev_->agentId) || agentId == agentId_)) {
852         connDev_->state = ConnectionState::DISCONNECTED;
853         OnConnectionChanged(*connDev_);
854     }
855 }
856 
OnInnerEvent(SharingEvent &event)857 void WfdSourceScene::OnInnerEvent(SharingEvent &event)
858 {
859     RETURN_IF_NULL(event.eventMsg);
860 
861     SHARING_LOGI("OnInnerEvent Type: %{public}s.", std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
862     switch (event.eventMsg->type) {
863         case EventType::EVENT_WFD_NOTIFY_RTSP_PLAYED: {
864             auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
865             if (msg) {
866                 std::lock_guard<std::mutex> lock(mutex_);
867                 if ((connDev_ == nullptr) || (connDev_->mac != msg->mac)) {
868                     SHARING_LOGE("connDev_ is nullptr or mac:%{private}s doesn't match.",
869                                  GetAnonyString(msg->mac).c_str());
870                     return;
871                 }
872                 connDev_->state = ConnectionState::PLAYING;
873                 OnConnectionChanged(*connDev_);
874             }
875             break;
876         }
877         case EventType::EVENT_WFD_NOTIFY_RTSP_TEARDOWN: {
878             auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
879             if (msg) {
880                 OnP2pPeerDisconnected(msg->mac);
881             }
882             break;
883         }
884         default:
885             SHARING_LOGI("none process case.");
886             break;
887     }
888 }
889 
OnConnectionChanged(ConnectionInfo &connectionInfo)890 void WfdSourceScene::OnConnectionChanged(ConnectionInfo &connectionInfo)
891 {
892     SHARING_LOGI("%{public}s.", __FUNCTION__);
893     auto ipcAdapter = ipcAdapter_.lock();
894     RETURN_IF_NULL(ipcAdapter);
895 
896     auto msg = std::make_shared<WfdConnectionChangedMsg>();
897     msg->ip = connectionInfo.ip;
898     msg->mac = connectionInfo.mac;
899     msg->state = connectionInfo.state;
900     msg->surfaceId = connectionInfo.surfaceId;
901     msg->deviceName = connectionInfo.deviceName;
902     msg->primaryDeviceType = connectionInfo.primaryDeviceType;
903     msg->secondaryDeviceType = connectionInfo.secondaryDeviceType;
904 
905     auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
906     ipcAdapter->SendRequest(msg, reply);
907 
908     if (connectionInfo.state == ConnectionState::CONNECTED) {
909         ResetCheckWfdConnectionTimer();
910         if (CreateScreenCapture() == ERR_OK) {
911             if (AppendCast(connectionInfo.mac) != 0) {
912                 SHARING_LOGE("append cast error.");
913                 OnInnerError(0, 0, SharingErrorCode::ERR_GENERAL_ERROR, "wfd connection timeout");
914             }
915         } else {
916             SHARING_LOGE("create screen capture error.");
917             OnInnerError(0, 0, SharingErrorCode::ERR_GENERAL_ERROR, "wfd connection timeout");
918         }
919     }
920 }
921 
OnRemoteDied()922 void WfdSourceScene::OnRemoteDied()
923 {
924     SHARING_LOGI("%{public}s.", __FUNCTION__);
925     auto sharingAdapter = sharingAdapter_.lock();
926     if (sharingAdapter) {
927         sharingAdapter->ReleaseScene(GetId());
928     }
929 }
930 
931 REGISTER_CLASS_REFLECTOR(WfdSourceScene);
932 } // namespace Sharing
933 } // namespace OHOS
934