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