• 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_sink_scene.h"
17 #include <unistd.h>
18 #include "common/common_macro.h"
19 #include "common/reflect_registration.h"
20 #include "common/sharing_log.h"
21 #include "configuration/include/config.h"
22 #include "const_def.h"
23 #include "extend/magic_enum/magic_enum.hpp"
24 #include "network/socket/socket_utils.h"
25 #include "utils/utils.h"
26 #include "wfd_session_def.h"
27 
28 namespace OHOS {
29 namespace Sharing {
30 
OnP2pStateChanged(int32_t state)31 void WfdSinkScene::WfdP2pCallback::OnP2pStateChanged(int32_t state)
32 {
33     SHARING_LOGD("state: %{public}d.", state);
34     auto parent = parent_.lock();
35     if (parent) {
36         switch (state) {
37             case (int32_t)Wifi::P2pState::P2P_STATE_NONE:
38                 break;
39             case (int32_t)Wifi::P2pState::P2P_STATE_IDLE:
40                 break;
41             case (int32_t)Wifi::P2pState::P2P_STATE_STARTING:
42                 break;
43             case (int32_t)Wifi::P2pState::P2P_STATE_STARTED:
44                 if (parent->isSinkRunning_) {
45                     parent->WfdP2pStart();
46                 }
47                 break;
48             case (int32_t)Wifi::P2pState::P2P_STATE_CLOSING:
49                 break;
50             case (int32_t)Wifi::P2pState::P2P_STATE_CLOSED:
51                 if (parent->isSinkRunning_) {
52                     parent->isSinkRunning_ = false;
53                     parent->WfdP2pStop();
54                     parent->OnInnerError("", SharingErrorCode::ERR_NETWORK_ERROR, "NETWORK ERROR, P2P MODULE STOPPED");
55                 }
56                 break;
57             default:
58                 SHARING_LOGI("none process case.");
59                 break;
60         }
61     }
62 }
63 
OnP2pPersistentGroupsChanged(void)64 void WfdSinkScene::WfdP2pCallback::OnP2pPersistentGroupsChanged(void)
65 {
66     SHARING_LOGD("trace.");
67 }
68 
OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice & device)69 void WfdSinkScene::WfdP2pCallback::OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice &device)
70 {
71     SHARING_LOGD("trace.");
72 }
73 
OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> & device)74 void WfdSinkScene::WfdP2pCallback::OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> &device)
75 {
76     SHARING_LOGD("trace.");
77     auto parent = parent_.lock();
78     if (parent) {
79         SHARING_LOGI("device size: %{public}zu.", device.size());
80         for (auto itDev : device) {
81             auto status = itDev.GetP2pDeviceStatus();
82             SHARING_LOGI("device mac: %{public}s, status: %{public}d.",
83                          GetAnonyString(itDev.GetDeviceAddress()).c_str(), status);
84             switch (status) {
85                 case Wifi::P2pDeviceStatus::PDS_AVAILABLE: {
86                     ConnectionInfo connectionInfo;
87                     connectionInfo.mac = itDev.GetDeviceAddress();
88                     connectionInfo.deviceName = itDev.GetDeviceName();
89                     connectionInfo.primaryDeviceType = itDev.GetPrimaryDeviceType();
90                     connectionInfo.secondaryDeviceType = itDev.GetSecondaryDeviceType();
91                     connectionInfo.ctrlPort = itDev.GetWfdInfo().GetCtrlPort();
92                     connectionInfo.state = ConnectionState::DISCONNECTED;
93 
94                     parent->OnP2pPeerDisconnected(connectionInfo);
95                     break;
96                 }
97                 default:
98                     SHARING_LOGI("none process case.");
99                     break;
100             }
101         }
102     }
103 }
104 
OnP2pPrivatePeersChanged(const std::string & priWfdInfo)105 void WfdSinkScene::WfdP2pCallback::OnP2pPrivatePeersChanged(const std::string &priWfdInfo)
106 {
107     SHARING_LOGD("trace.");
108 }
109 
OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> & srvInfo)110 void WfdSinkScene::WfdP2pCallback::OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> &srvInfo)
111 {
112     SHARING_LOGD("trace.");
113 }
114 
OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo & info)115 void WfdSinkScene::WfdP2pCallback::OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo &info)
116 {
117     SHARING_LOGD("trace.");
118 }
119 
OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo & info)120 void WfdSinkScene::WfdP2pCallback::OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo &info)
121 {
122     SHARING_LOGD("trace.");
123     auto parent = parent_.lock();
124     if (parent && parent->p2pInstance_) {
125         std::vector<Wifi::WifiP2pDevice> devices;
126         if (Wifi::ErrCode::WIFI_OPT_SUCCESS != parent->p2pInstance_->QueryP2pDevices(devices)) {
127             SHARING_LOGE("QueryP2pDevices failed");
128             return;
129         }
130         SHARING_LOGI("QueryP2pDevices ip:%{private}s addr: %{private}s host: %{private}s.",
131                      GetAnonyString(info.ip).c_str(), GetAnonyString(info.mac).c_str(),
132                      GetAnonyString(info.host).c_str());
133         if (info.ip == "0.0.0.0" || info.ip == "") {
134             SHARING_LOGE("device: %{private}s leased ip is: 0.0.0.0.", GetAnonyString(info.mac).c_str());
135             parent->OnInnerError(info.mac.c_str(), ERR_P2P_DHCP_INVALID_IP, "ip is: 0.0.0.0.");
136             return;
137         }
138 
139         for (auto itDev : devices) {
140             ConnectionInfo connectionInfo;
141             connectionInfo.ip = info.ip;
142             connectionInfo.mac = itDev.GetDeviceAddress();
143             connectionInfo.primaryDeviceType = itDev.GetPrimaryDeviceType();
144             connectionInfo.secondaryDeviceType = itDev.GetSecondaryDeviceType();
145             connectionInfo.ctrlPort = itDev.GetWfdInfo().GetCtrlPort();
146             connectionInfo.state = ConnectionState::CONNECTED;
147             SHARING_LOGD("device connected, mac: %{private}s, ip: %{private}s, port: %{private}d",
148                          connectionInfo.mac.c_str(), connectionInfo.ip.c_str(), connectionInfo.ctrlPort);
149             parent->OnP2pPeerConnected(connectionInfo);
150             return;
151         }
152     }
153 }
154 
OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo & info)155 void WfdSinkScene::WfdP2pCallback::OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo &info)
156 {
157     return;
158 }
159 
OnP2pDiscoveryChanged(bool isChange)160 void WfdSinkScene::WfdP2pCallback::OnP2pDiscoveryChanged(bool isChange)
161 {
162     SHARING_LOGD("isChange: %{public}d.", isChange);
163 }
164 
OnP2pActionResult(Wifi::P2pActionCallback action,Wifi::ErrCode code)165 void WfdSinkScene::WfdP2pCallback::OnP2pActionResult(Wifi::P2pActionCallback action, Wifi::ErrCode code)
166 {
167     SHARING_LOGD("trace.");
168 }
169 
OnConfigChanged(Wifi::CfgType type,char * data,int32_t dataLen)170 void WfdSinkScene::WfdP2pCallback::OnConfigChanged(Wifi::CfgType type, char *data, int32_t dataLen)
171 {
172     SHARING_LOGD("trace.");
173 }
174 
WfdSinkScene()175 WfdSinkScene::WfdSinkScene()
176 {
177     SHARING_LOGI("id: %{public}u.", GetId());
178 }
179 
~WfdSinkScene()180 WfdSinkScene::~WfdSinkScene()
181 {
182     SHARING_LOGI("id: %{public}u.", GetId());
183     Release();
184 }
185 
Initialize()186 void WfdSinkScene::Initialize()
187 {
188     SHARING_LOGD("trace.");
189     SharingValue::Ptr values = nullptr;
190 
191     auto ret = Config::GetInstance().GetConfig("sharingWfd", "ctrlport", "defaultWfdCtrlport", values);
192     if (ret == CONFIGURE_ERROR_NONE) {
193         values->GetValue<int32_t>(ctrlPort_);
194     }
195 
196     ret = Config::GetInstance().GetConfig("sharingWfd", "abilityLimit", "accessDevMaximum", values);
197     if (ret == CONFIGURE_ERROR_NONE) {
198         values->GetValue<int32_t>(accessDevMaximum_);
199     }
200 
201     ret = Config::GetInstance().GetConfig("sharingWfd", "abilityLimit", "surfaceMaximum", values);
202     if (ret == CONFIGURE_ERROR_NONE) {
203         values->GetValue<int32_t>(surfaceMaximum_);
204     }
205 
206     ret = Config::GetInstance().GetConfig("sharingWfd", "abilityLimit", "foregroundMaximum", values);
207     if (ret == CONFIGURE_ERROR_NONE) {
208         values->GetValue<int32_t>(foregroundMaximum_);
209     }
210 
211     ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "videoCodec", values);
212     if (ret == CONFIGURE_ERROR_NONE) {
213         int32_t videoCodec;
214         values->GetValue<int32_t>(videoCodec);
215         videoCodecId_ = static_cast<CodecId>(videoCodec);
216     }
217 
218     ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "videoFormat", values);
219     if (ret == CONFIGURE_ERROR_NONE) {
220         int32_t videoFormat;
221         values->GetValue<int32_t>(videoFormat);
222         videoFormatId_ = static_cast<VideoFormat>(videoFormat);
223     }
224 
225     ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "audioCodec", values);
226     if (ret == CONFIGURE_ERROR_NONE) {
227         int32_t audioCodec;
228         values->GetValue<int32_t>(audioCodec);
229         audioCodecId_ = static_cast<CodecId>(audioCodec);
230     }
231 
232     ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "audioFormat", values);
233     if (ret == CONFIGURE_ERROR_NONE) {
234         int32_t audioFormat;
235         values->GetValue<int32_t>(audioFormat);
236         audioFormatId_ = static_cast<AudioFormat>(audioFormat);
237     }
238 
239     p2pInstance_ = Wifi::WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
240     RETURN_IF_NULL(p2pInstance_);
241     sptr<WfdP2pCallback> wfdP2pCallback(new WfdP2pCallback(shared_from_this()));
242     std::vector<std::string> event = {EVENT_P2P_PEER_DEVICE_CHANGE, EVENT_P2P_CONN_STATE_CHANGE,
243                                       EVENT_P2P_GC_JOIN_GROUP, EVENT_P2P_GC_LEAVE_GROUP};
244     p2pInstance_->RegisterCallBack(wfdP2pCallback, event);
245 }
246 
Release()247 void WfdSinkScene::Release()
248 {
249     SHARING_LOGD("trace.");
250     std::unique_lock<std::mutex> lock(mutex_);
251     auto sharingAdapter = sharingAdapter_.lock();
252     if (sharingAdapter != nullptr) {
253         for (auto &item : devConnectionMap_) {
254             uint32_t contextId = INVALID_ID;
255             uint32_t agentId = INVALID_ID;
256             if (item.second == nullptr) {
257                 continue;
258             }
259 
260             contextId = item.second->contextId;
261             agentId = item.second->agentId;
262 
263             if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
264                 continue;
265             }
266 
267             auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
268             sessionMsg->type = EVENT_SESSION_TEARDOWN;
269             sessionMsg->toMgr = MODULE_CONTEXT;
270             sessionMsg->dstId = contextId;
271             sessionMsg->agentId = agentId;
272 
273             SharingEvent event;
274             event.eventMsg = std::move(sessionMsg);
275             sharingAdapter->ForwardEvent(contextId, agentId, event, true);
276 
277             P2pRemoveClient(*(item.second));
278 
279             sharingAdapter->DestroyAgent(contextId, agentId);
280         }
281     }
282 
283     if (p2pInstance_) {
284         SHARING_LOGW("DisableP2p before.");
285         p2pInstance_->RemoveGroup();
286         SHARING_LOGW("DisableP2p end.");
287     }
288 
289     devConnectionMap_.clear();
290     devSurfaceItemMap_.clear();
291     p2pInstance_.reset();
292 }
293 
OnDomainMsg(std::shared_ptr<BaseDomainMsg> & msg)294 void WfdSinkScene::OnDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)
295 {
296     SHARING_LOGD("trace.");
297 }
298 
OnRequest(std::shared_ptr<BaseMsg> msg,std::shared_ptr<BaseMsg> & reply)299 void WfdSinkScene::OnRequest(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)
300 {
301     SHARING_LOGD("trace.");
302     RETURN_IF_NULL(msg);
303     SHARING_LOGI("recv msg, msg id: %{public}d.", msg->GetMsgId());
304     switch (msg->GetMsgId()) {
305         case WfdSinkStartReq::MSG_ID: {
306             auto data = std::static_pointer_cast<WfdSinkStartReq>(msg);
307             auto rsp = std::make_shared<WfdCommonRsp>();
308 
309             rsp->ret = HandleStart(data, rsp);
310             reply = std::static_pointer_cast<BaseMsg>(rsp);
311             break;
312         }
313         case WfdSinkStopReq::MSG_ID: {
314             auto data = std::static_pointer_cast<WfdSinkStopReq>(msg);
315             auto rsp = std::make_shared<WfdCommonRsp>();
316 
317             rsp->ret = HandleStop(data, rsp);
318             reply = std::static_pointer_cast<BaseMsg>(rsp);
319             break;
320         }
321         case WfdAppendSurfaceReq::MSG_ID: {
322             auto data = std::static_pointer_cast<WfdAppendSurfaceReq>(msg);
323             auto rsp = std::make_shared<WfdCommonRsp>();
324 
325             rsp->ret = HandleAppendSurface(data, rsp);
326             reply = std::static_pointer_cast<BaseMsg>(rsp);
327             break;
328         }
329         case WfdRemoveSurfaceReq::MSG_ID: {
330             auto data = std::static_pointer_cast<WfdRemoveSurfaceReq>(msg);
331             auto rsp = std::make_shared<WfdCommonRsp>();
332 
333             rsp->ret = HandleRemoveSurface(data, rsp);
334             reply = std::static_pointer_cast<BaseMsg>(rsp);
335             break;
336         }
337         case SetMediaFormatReq::MSG_ID: {
338             auto data = std::static_pointer_cast<SetMediaFormatReq>(msg);
339             auto rsp = std::make_shared<WfdCommonRsp>();
340 
341             rsp->ret = HandleSetMediaFormat(data, rsp);
342             reply = std::static_pointer_cast<BaseMsg>(rsp);
343             break;
344         }
345         case SetSceneTypeReq::MSG_ID: {
346             auto data = std::static_pointer_cast<SetSceneTypeReq>(msg);
347             auto rsp = std::make_shared<WfdCommonRsp>();
348 
349             rsp->ret = HandleSetSceneType(data, rsp);
350             reply = std::static_pointer_cast<BaseMsg>(rsp);
351             break;
352         }
353         case WfdPlayReq::MSG_ID: {
354             auto data = std::static_pointer_cast<WfdPlayReq>(msg);
355             auto rsp = std::make_shared<WfdCommonRsp>();
356 
357             rsp->ret = HandlePlay(data, rsp);
358             reply = std::static_pointer_cast<BaseMsg>(rsp);
359             break;
360         }
361         case WfdPauseReq::MSG_ID: {
362             auto data = std::static_pointer_cast<WfdPauseReq>(msg);
363             auto rsp = std::make_shared<WfdCommonRsp>();
364 
365             rsp->ret = HandlePause(data, rsp);
366             reply = std::static_pointer_cast<BaseMsg>(rsp);
367             break;
368         }
369         case MuteReq::MSG_ID: {
370             auto data = std::static_pointer_cast<MuteReq>(msg);
371             auto rsp = std::make_shared<WfdCommonRsp>();
372 
373             rsp->ret = HandleMute(data, rsp);
374             reply = std::static_pointer_cast<BaseMsg>(rsp);
375             break;
376         }
377         case UnMuteReq::MSG_ID: {
378             auto data = std::static_pointer_cast<UnMuteReq>(msg);
379             auto rsp = std::make_shared<WfdCommonRsp>();
380 
381             rsp->ret = HandleUnMute(data, rsp);
382             reply = std::static_pointer_cast<BaseMsg>(rsp);
383             break;
384         }
385         case WfdCloseReq::MSG_ID: {
386             auto data = std::static_pointer_cast<WfdCloseReq>(msg);
387             auto rsp = std::make_shared<WfdCommonRsp>();
388 
389             rsp->ret = HandleClose(data, rsp);
390             reply = std::static_pointer_cast<BaseMsg>(rsp);
391             break;
392         }
393         case GetSinkConfigReq::MSG_ID: {
394             auto data = std::static_pointer_cast<GetSinkConfigReq>(msg);
395             auto rsp = std::make_shared<GetSinkConfigRsp>();
396 
397             rsp->foregroundMaximum = INVALID_ID;
398             HandleGetConfig(data, rsp);
399             reply = std::static_pointer_cast<BaseMsg>(rsp);
400             break;
401         }
402         default:
403             SHARING_LOGW("unknown msg request.");
404             break;
405     }
406 }
407 
HandleStart(std::shared_ptr<WfdSinkStartReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)408 int32_t WfdSinkScene::HandleStart(std::shared_ptr<WfdSinkStartReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
409 {
410     SHARING_LOGD("trace.");
411     (void)msg;
412     (void)reply;
413     if (isSinkRunning_) {
414         SHARING_LOGW("p2p sink is running.");
415         return 0;
416     }
417     RETURN_INVALID_IF_NULL(p2pInstance_);
418     int32_t ret = 0;
419     int32_t status = 0;
420     p2pInstance_->GetP2pEnableStatus(status);
421     switch (status) {
422         case (int32_t)Wifi::P2pState::P2P_STATE_NONE:
423         case (int32_t)Wifi::P2pState::P2P_STATE_IDLE:
424         case (int32_t)Wifi::P2pState::P2P_STATE_STARTING:
425         case (int32_t)Wifi::P2pState::P2P_STATE_CLOSING:
426             OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "HandleStart current p2p state: CLOSING");
427             ret = -1;
428             break;
429         case (int32_t)Wifi::P2pState::P2P_STATE_STARTED:
430             isSinkRunning_ = true;
431             WfdP2pStart();
432             break;
433         case (int32_t)Wifi::P2pState::P2P_STATE_CLOSED:
434             isSinkRunning_ = true;
435             p2pInstance_->EnableP2p();
436             break;
437         default:
438             SHARING_LOGI("none process case.");
439             break;
440     }
441 
442     return ret;
443 }
444 
HandleStop(std::shared_ptr<WfdSinkStopReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)445 int32_t WfdSinkScene::HandleStop(std::shared_ptr<WfdSinkStopReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
446 {
447     SHARING_LOGD("handle stop, now connect device num: %{public}zu.", devConnectionMap_.size());
448     (void)msg;
449     (void)reply;
450     if (!isSinkRunning_) {
451         SHARING_LOGW("p2p sink is not running.");
452         return -1;
453     }
454 
455     isSinkRunning_ = false;
456     WfdP2pStop();
457 
458     return 0;
459 }
460 
HandleAppendSurface(std::shared_ptr<WfdAppendSurfaceReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)461 int32_t WfdSinkScene::HandleAppendSurface(std::shared_ptr<WfdAppendSurfaceReq> &msg,
462                                           std::shared_ptr<WfdCommonRsp> &reply)
463 {
464     SHARING_LOGD("trace.");
465     (void)reply;
466     RETURN_INVALID_IF_NULL(msg);
467     auto sharingAdapter = sharingAdapter_.lock();
468     RETURN_INVALID_IF_NULL(sharingAdapter);
469 
470     {
471         std::unique_lock<std::mutex> lock(mutex_);
472         auto itemDev = devConnectionMap_.find(msg->deviceId);
473         if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
474             lock.unlock();
475             SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
476             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleAppendSurface can't find the dev");
477             return -1;
478         }
479         int32_t surfaceNum = 0;
480         for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
481             if (!itemSurface->second->deleting) {
482                 surfaceNum++;
483             }
484             itemSurface++;
485         }
486 
487         if (surfaceNum >= surfaceMaximum_) {
488             lock.unlock();
489             SHARING_LOGE("surface is too much.");
490             OnInnerError(0, 0, SharingErrorCode::ERR_SERVICE_LIMIT, "HandleAppendSurface surface is too much");
491             return -1;
492         }
493 
494         sptr<IBufferProducer> producer = iface_cast<IBufferProducer>(msg->surface);
495         sptr<Surface> surfacePtr = Surface::CreateSurfaceAsProducer(producer);
496         if (surfacePtr == nullptr) {
497             SHARING_LOGE("invalid surface.");
498             return -1;
499         }
500 
501         uint64_t surfaceId = surfacePtr->GetUniqueId();
502         SHARING_LOGI("get surfaceId %{public}" PRIx64 ".", surfaceId);
503         if (devSurfaceItemMap_.count(surfaceId)) {
504             SHARING_LOGW("this surface is using, surfaceId: %{public}" PRIx64 ".", surfaceId);
505             lock.unlock();
506             OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "HandleAppendSurface this surface is using");
507             return ERR_STATE_EXCEPTION;
508         }
509 
510         int32_t foregroundSurfaceNum = 0;
511         for (auto item : devSurfaceItemMap_) {
512             if ((item.second != nullptr) && (item.second->deviceId == msg->deviceId) && (!item.second->deleting)) {
513                 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "Only one surface can be set.");
514                 return ERR_STATE_EXCEPTION;
515             }
516 
517             if (item.second->sceneType == SceneType::FOREGROUND) {
518                 foregroundSurfaceNum++;
519             }
520         }
521 
522         auto devSurfaceItem = std::make_shared<DevSurfaceItem>();
523         devSurfaceItem->contextId = itemDev->second->contextId;
524         devSurfaceItem->agentId = itemDev->second->agentId;
525         devSurfaceItem->deviceId = itemDev->second->mac;
526         devSurfaceItem->surfacePtr = surfacePtr;
527         devSurfaceItem->sceneType = (foregroundSurfaceNum >= foregroundMaximum_) ? BACKGROUND : FOREGROUND;
528         devSurfaceItemMap_.emplace(surfaceId, devSurfaceItem);
529 
530         if (itemDev->second->isRunning) {
531             uint32_t contextId = itemDev->second->contextId;
532             uint32_t agentId = itemDev->second->agentId;
533 
534             auto startSessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
535             startSessionMsg->type = EVENT_WFD_REQUEST_IDR;
536             startSessionMsg->toMgr = MODULE_CONTEXT;
537             startSessionMsg->dstId = contextId;
538             startSessionMsg->agentId = agentId;
539 
540             SharingEvent event;
541             event.eventMsg = std::move(startSessionMsg);
542             if (sharingAdapter) {
543                 sharingAdapter->ForwardEvent(contextId, agentId, event, false);
544                 sharingAdapter->AppendSurface(itemDev->second->contextId, itemDev->second->agentId, surfacePtr,
545                                               devSurfaceItem->sceneType);
546             }
547         }
548     }
549     return 0;
550 }
551 
HandleRemoveSurface(std::shared_ptr<WfdRemoveSurfaceReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)552 int32_t WfdSinkScene::HandleRemoveSurface(std::shared_ptr<WfdRemoveSurfaceReq> &msg,
553                                           std::shared_ptr<WfdCommonRsp> &reply)
554 {
555     SHARING_LOGD("trace.");
556     (void)reply;
557     RETURN_INVALID_IF_NULL(msg);
558     auto sharingAdapter = sharingAdapter_.lock();
559     RETURN_INVALID_IF_NULL(sharingAdapter);
560     {
561         std::unique_lock<std::mutex> lock(mutex_);
562         auto itemDev = devConnectionMap_.find(msg->deviceId);
563         if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
564             lock.unlock();
565             SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
566             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleRemoveSurface can't find the dev");
567             return -1;
568         }
569 
570         auto item = devSurfaceItemMap_.find(msg->surfaceId);
571         if (item == devSurfaceItemMap_.end()) {
572             lock.unlock();
573             SHARING_LOGE("can not find surfaceid, surfaceid: %{public}" PRId64 ".", msg->surfaceId);
574             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleAppendSurface can't find the dev");
575             return -1;
576         }
577 
578         SHARING_LOGW("del surface, surfaceid: %{public}" PRId64 ".", msg->surfaceId);
579         sharingAdapter->RemoveSurface(itemDev->second->contextId, itemDev->second->agentId, msg->surfaceId);
580     }
581 
582     return 0;
583 }
584 
HandleSetMediaFormat(std::shared_ptr<SetMediaFormatReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)585 int32_t WfdSinkScene::HandleSetMediaFormat(std::shared_ptr<SetMediaFormatReq> &msg,
586                                            std::shared_ptr<WfdCommonRsp> &reply)
587 {
588     SHARING_LOGD("trace.");
589     (void)reply;
590     RETURN_INVALID_IF_NULL(msg);
591     {
592         std::unique_lock<std::mutex> lock(mutex_);
593         auto itemDev = devConnectionMap_.find(msg->deviceId);
594         if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
595             lock.unlock();
596             SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
597             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleSetMediaFormat can not find dev");
598             return -1;
599         }
600         itemDev->second->videoCodecId = static_cast<CodecId>(msg->videoAttr.codecType);
601         itemDev->second->videoFormatId = static_cast<VideoFormat>(msg->videoAttr.formatId);
602         itemDev->second->audioCodecId = static_cast<CodecId>(msg->audioAttr.codecType);
603         itemDev->second->audioFormatId = static_cast<AudioFormat>(msg->audioAttr.formatId);
604     }
605 
606     return 0;
607 }
608 
HandleSetSceneType(std::shared_ptr<SetSceneTypeReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)609 int32_t WfdSinkScene::HandleSetSceneType(std::shared_ptr<SetSceneTypeReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
610 {
611     SHARING_LOGD("trace.");
612     (void)reply;
613     RETURN_INVALID_IF_NULL(msg);
614     auto sharingAdapter = sharingAdapter_.lock();
615     RETURN_INVALID_IF_NULL(sharingAdapter);
616 
617     uint32_t contextId = INVALID_ID;
618     uint32_t agentId = INVALID_ID;
619     {
620         std::unique_lock<std::mutex> lock(mutex_);
621         auto itemDev = devConnectionMap_.find(msg->deviceId);
622         if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
623             lock.unlock();
624             SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
625             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleSetSceneType can not find dev");
626             return -1;
627         }
628 
629         auto itemSurface = devSurfaceItemMap_.find(msg->surfaceId);
630         if ((itemSurface == devSurfaceItemMap_.end()) || (itemSurface->second) || (itemSurface->second->deleting)) {
631             lock.unlock();
632             SHARING_LOGE("can not find surfaceid, surfaceid: %{public}" PRId64 ".", msg->surfaceId);
633             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleSetSceneType can't find the surfaceId");
634             return -1;
635         }
636 
637         contextId = itemDev->second->contextId;
638         agentId = itemDev->second->agentId;
639 
640         uint32_t foregroundSurfaceNum = 1;
641         if (msg->sceneType == SceneType::FOREGROUND) {
642             for (auto item : devSurfaceItemMap_) {
643                 if ((item.first == msg->surfaceId) && (!item.second->deleting)) {
644                     continue;
645                 }
646 
647                 if (item.second->sceneType == SceneType::FOREGROUND) {
648                     foregroundSurfaceNum++;
649                 }
650             }
651 
652             if (foregroundSurfaceNum > (uint32_t)foregroundMaximum_) {
653                 lock.unlock();
654                 SHARING_LOGE("foreground surfaces is too much.");
655                 OnInnerError(0, 0, SharingErrorCode::ERR_SERVICE_LIMIT,
656                              "HandleSetSceneType foreground surfaces is too much");
657                 return -1;
658             } else {
659                 itemSurface->second->sceneType = SceneType::FOREGROUND;
660             }
661         } else {
662             itemSurface->second->sceneType = SceneType::BACKGROUND;
663         }
664     }
665 
666     if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
667         SHARING_LOGW("invalid contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
668         return 0;
669     }
670 
671     bool keyFrame = msg->sceneType == SceneType::BACKGROUND ? true : false;
672     auto ret = sharingAdapter->SetKeyPlay(contextId, agentId, msg->surfaceId, keyFrame);
673     if (!keyFrame) {
674         sharingAdapter->SetKeyRedirect(contextId, agentId, msg->surfaceId, true);
675     }
676 
677     return ret;
678 }
679 
HandlePlay(std::shared_ptr<WfdPlayReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)680 int32_t WfdSinkScene::HandlePlay(std::shared_ptr<WfdPlayReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
681 {
682     SHARING_LOGD("trace.");
683     (void)reply;
684     RETURN_INVALID_IF_NULL(msg);
685     auto sharingAdapter = sharingAdapter_.lock();
686     RETURN_INVALID_IF_NULL(sharingAdapter);
687 
688     {
689         std::unique_lock<std::mutex> lock(mutex_);
690         auto itemDev = devConnectionMap_.find(msg->deviceId);
691         if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
692             lock.unlock();
693             SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
694             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandlePlay can not find dev");
695             return -1;
696         }
697 
698         uint32_t contextId = itemDev->second->contextId;
699         uint32_t agentId = itemDev->second->agentId;
700         if (contextId == INVALID_ID || agentId == INVALID_ID) {
701             lock.unlock();
702             SHARING_LOGE("connected, create sink agent failed, devMac: %{private}s.",
703                          GetAnonyString(msg->deviceId).c_str());
704             return -1;
705         }
706 
707         if (itemDev->second->isRunning == true) {
708             lock.unlock();
709             return sharingAdapter->Resume(contextId, agentId, MEDIA_TYPE_AV);
710         } else {
711             itemDev->second->isRunning = true;
712         }
713 
714         lock.unlock();
715 
716         auto startSessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
717         startSessionMsg->type = EVENT_SESSION_INIT;
718         startSessionMsg->toMgr = MODULE_CONTEXT;
719         startSessionMsg->dstId = contextId;
720         startSessionMsg->agentId = agentId;
721         startSessionMsg->ip = itemDev->second->ip;
722         startSessionMsg->mac = itemDev->second->mac;
723         startSessionMsg->remotePort = itemDev->second->ctrlPort;
724         startSessionMsg->videoFormat = itemDev->second->videoFormatId;
725         startSessionMsg->audioFormat = itemDev->second->audioFormatId;
726         startSessionMsg->localPort = SocketUtils::GetAvailableUdpPortPair();
727 
728         SharingEvent event;
729         event.eventMsg = std::move(startSessionMsg);
730 
731         sharingAdapter->ForwardEvent(contextId, agentId, event, true);
732         sharingAdapter->Start(contextId, agentId);
733 
734         for (auto &item : devSurfaceItemMap_) {
735             if ((item.second != nullptr) && (itemDev->first == item.second->deviceId) && (!item.second->deleting)) {
736                 if (item.second->surfacePtr != nullptr) {
737                     sharingAdapter->AppendSurface(contextId, agentId, item.second->surfacePtr, item.second->sceneType);
738                 }
739             }
740         }
741 
742         sharingAdapter->Play(contextId, agentId);
743     }
744 
745     return 0;
746 }
747 
HandlePause(std::shared_ptr<WfdPauseReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)748 int32_t WfdSinkScene::HandlePause(std::shared_ptr<WfdPauseReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
749 {
750     SHARING_LOGD("trace.");
751     (void)reply;
752     RETURN_INVALID_IF_NULL(msg);
753     auto sharingAdapter = sharingAdapter_.lock();
754     RETURN_INVALID_IF_NULL(sharingAdapter);
755 
756     uint32_t contextId = INVALID_ID;
757     uint32_t agentId = INVALID_ID;
758     {
759         std::unique_lock<std::mutex> lock(mutex_);
760         auto itemDev = devConnectionMap_.find(msg->deviceId);
761         if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
762             lock.unlock();
763             SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
764             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandlePause can not find dev");
765             return -1;
766         }
767 
768         contextId = itemDev->second->contextId;
769         agentId = itemDev->second->agentId;
770     }
771 
772     if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
773         return -1;
774     }
775 
776     return sharingAdapter->Pause(contextId, agentId, MEDIA_TYPE_AV);
777 }
778 
HandleMute(std::shared_ptr<MuteReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)779 int32_t WfdSinkScene::HandleMute(std::shared_ptr<MuteReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
780 {
781     SHARING_LOGD("trace.");
782     (void)reply;
783     RETURN_INVALID_IF_NULL(msg);
784     auto sharingAdapter = sharingAdapter_.lock();
785     RETURN_INVALID_IF_NULL(sharingAdapter);
786 
787     uint32_t contextId = INVALID_ID;
788     uint32_t agentId = INVALID_ID;
789     {
790         std::unique_lock<std::mutex> lock(mutex_);
791         auto itemDev = devConnectionMap_.find(msg->deviceId);
792         if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
793             lock.unlock();
794             SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
795             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleMute can not find dev");
796             return -1;
797         }
798 
799         contextId = itemDev->second->contextId;
800         agentId = itemDev->second->agentId;
801     }
802 
803     if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
804         return -1;
805     }
806 
807     return sharingAdapter->Pause(contextId, agentId, MEDIA_TYPE_AUDIO);
808 }
809 
HandleUnMute(std::shared_ptr<UnMuteReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)810 int32_t WfdSinkScene::HandleUnMute(std::shared_ptr<UnMuteReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
811 {
812     SHARING_LOGD("trace.");
813     (void)reply;
814     RETURN_INVALID_IF_NULL(msg);
815     auto sharingAdapter = sharingAdapter_.lock();
816     RETURN_INVALID_IF_NULL(sharingAdapter);
817 
818     uint32_t contextId = INVALID_ID;
819     uint32_t agentId = INVALID_ID;
820     {
821         std::unique_lock<std::mutex> lock(mutex_);
822         auto itemDev = devConnectionMap_.find(msg->deviceId);
823         if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
824             lock.unlock();
825             SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
826             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleUnMute can not find dev");
827             return -1;
828         }
829 
830         contextId = itemDev->second->contextId;
831         agentId = itemDev->second->agentId;
832     }
833 
834     if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
835         return -1;
836     }
837 
838     return sharingAdapter->Resume(contextId, agentId, MEDIA_TYPE_AUDIO);
839 }
840 
HandleClose(std::shared_ptr<WfdCloseReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)841 int32_t WfdSinkScene::HandleClose(std::shared_ptr<WfdCloseReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
842 {
843     SHARING_LOGD("trace.");
844     (void)reply;
845     RETURN_INVALID_IF_NULL(msg);
846     auto sharingAdapter = sharingAdapter_.lock();
847     RETURN_INVALID_IF_NULL(sharingAdapter);
848 
849     uint32_t contextId = INVALID_ID;
850     uint32_t agentId = INVALID_ID;
851     ConnectionInfo connectionInfo;
852     {
853         std::unique_lock<std::mutex> lock(mutex_);
854         auto itemDev = devConnectionMap_.find(msg->deviceId);
855         if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
856             lock.unlock();
857             SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
858             OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleClose can not find dev");
859             return -1;
860         }
861 
862         connectionInfo.ip = itemDev->second->ip;
863         connectionInfo.mac = itemDev->second->mac;
864         connectionInfo.state = ConnectionState::DISCONNECTED;
865         connectionInfo.surfaceId = itemDev->second->surfaceId;
866         connectionInfo.deviceName = itemDev->second->deviceName;
867         connectionInfo.primaryDeviceType = itemDev->second->primaryDeviceType;
868         connectionInfo.secondaryDeviceType = itemDev->second->secondaryDeviceType;
869 
870         contextId = itemDev->second->contextId;
871         agentId = itemDev->second->agentId;
872 
873         for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
874             if ((itemSurface->second != nullptr) && (msg->deviceId == itemSurface->second->deviceId)) {
875                 itemSurface->second->deleting = true;
876             }
877             itemSurface++;
878         }
879 
880         P2pRemoveClient(connectionInfo);
881 
882         devConnectionMap_.erase(msg->deviceId);
883     }
884 
885     if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
886         return -1;
887     }
888 
889     OnConnectionChanged(connectionInfo);
890     auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
891     sessionMsg->type = EVENT_SESSION_TEARDOWN;
892     sessionMsg->toMgr = MODULE_CONTEXT;
893     sessionMsg->dstId = contextId;
894     sessionMsg->agentId = agentId;
895 
896     SharingEvent event;
897     event.eventMsg = std::move(sessionMsg);
898     sharingAdapter->ForwardEvent(contextId, agentId, event, true);
899 
900     return sharingAdapter->DestroyAgent(contextId, agentId);
901 }
902 
HandleGetConfig(std::shared_ptr<GetSinkConfigReq> & msg,std::shared_ptr<GetSinkConfigRsp> & reply)903 int32_t WfdSinkScene::HandleGetConfig(std::shared_ptr<GetSinkConfigReq> &msg, std::shared_ptr<GetSinkConfigRsp> &reply)
904 {
905     SHARING_LOGD("trace.");
906     (void)msg;
907     RETURN_INVALID_IF_NULL(reply);
908     reply->accessDevMaximum = accessDevMaximum_;
909     reply->foregroundMaximum = foregroundMaximum_;
910     reply->surfaceMaximum = surfaceMaximum_;
911 
912     return 0;
913 }
914 
WfdP2pStart()915 void WfdSinkScene::WfdP2pStart()
916 {
917     SHARING_LOGD("trace.");
918     if (p2pInstance_) {
919         p2pInstance_->RemoveGroup();
920 
921         Wifi::WifiP2pWfdInfo wfdInfo;
922         wfdInfo.SetWfdEnabled(true);
923         wfdInfo.SetDeviceInfo(0x11);
924         wfdInfo.SetCtrlPort(ctrlPort_);
925         wfdInfo.SetMaxThroughput(0x00c8);
926 
927         p2pInstance_->SetP2pWfdInfo(wfdInfo);
928 
929         SHARING_LOGD("WfdSinkScene CreateGroup.");
930         std::vector<Wifi::WifiP2pGroupInfo> p2pGroups;
931         p2pInstance_->QueryP2pGroups(p2pGroups);
932 
933         int32_t netWokrId = -2;
934         if (!p2pGroups.empty()) {
935             SHARING_LOGD("WfdSinkScene p2p group exists, the netWorkId:%{public}d.", netWokrId);
936         }
937 
938         Wifi::WifiP2pDevice p2pDev;
939         p2pInstance_->QueryP2pLocalDevice(p2pDev);
940         auto hostAddr = p2pDev.GetDeviceAddress();
941 
942         Wifi::WifiP2pConfig cfg;
943         cfg.SetGoBand(Wifi::GroupOwnerBand::GO_BAND_5GHZ);
944         cfg.SetNetId(netWokrId);
945         cfg.SetDeviceAddress(hostAddr);
946 
947         p2pInstance_->CreateGroup(cfg);
948         SHARING_LOGD("WfdSinkScene DiscoverDevices.");
949     }
950 }
951 
WfdP2pStop()952 void WfdSinkScene::WfdP2pStop()
953 {
954     SHARING_LOGD("trace.");
955     std::unique_lock<std::mutex> lock(mutex_);
956     auto sharingAdapter = sharingAdapter_.lock();
957     if (sharingAdapter != nullptr) {
958         for (auto item : devConnectionMap_) {
959             uint32_t contextId = item.second->contextId;
960             uint32_t agentId = item.second->agentId;
961 
962             if ((contextId != INVALID_ID) && (agentId != INVALID_ID)) {
963                 auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
964                 sessionMsg->type = EVENT_SESSION_TEARDOWN;
965                 sessionMsg->toMgr = MODULE_CONTEXT;
966                 sessionMsg->dstId = contextId;
967                 sessionMsg->agentId = agentId;
968 
969                 SharingEvent event;
970                 event.eventMsg = std::move(sessionMsg);
971                 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
972 
973                 P2pRemoveClient(*(item.second));
974 
975                 sharingAdapter->DestroyAgent(contextId, agentId);
976             }
977         }
978     }
979 
980     if (p2pInstance_) {
981         SHARING_LOGW("DisableP2p before.");
982         p2pInstance_->StopDiscoverDevices();
983         p2pInstance_->RemoveGroup();
984         SHARING_LOGW("DisableP2p end.");
985     }
986 
987     devSurfaceItemMap_.clear();
988     devConnectionMap_.clear();
989 }
990 
OnP2pPeerConnected(ConnectionInfo & connectionInfo)991 void WfdSinkScene::OnP2pPeerConnected(ConnectionInfo &connectionInfo)
992 {
993     SHARING_LOGD("trace.");
994     if (!isSinkRunning_) {
995         SHARING_LOGW("sink service is not running.");
996         return;
997     }
998 
999     auto sharingAdapter = sharingAdapter_.lock();
1000     RETURN_IF_NULL(sharingAdapter);
1001 
1002     if (devConnectionMap_.size() >= (uint32_t)accessDevMaximum_) {
1003         SHARING_LOGE("too more device.");
1004         P2pRemoveClient(connectionInfo);
1005 
1006         auto ipcAdapter = ipcAdapter_.lock();
1007         RETURN_IF_NULL(ipcAdapter);
1008 
1009         auto msg = std::make_shared<WfdErrorMsg>();
1010         msg->message = "Maximum number of devices reached";
1011         msg->errorCode = ERR_RECEIVING_LIMIT;
1012 
1013         auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1014         ipcAdapter->SendRequest(msg, reply);
1015 
1016         return;
1017     }
1018 
1019     {
1020         std::unique_lock<std::mutex> lock(mutex_);
1021         if (devConnectionMap_.count(connectionInfo.mac)) {
1022             SHARING_LOGW("devcie is alerady connected, mac: %{private}s.", GetAnonyString(connectionInfo.mac).c_str());
1023             return;
1024         }
1025 
1026         uint32_t contextId = INVALID_ID;
1027         uint32_t agentId = INVALID_ID;
1028 
1029         sharingAdapter->CreateAgent(contextId, agentId, AgentType::SINK_AGENT, "WfdSinkSession");
1030         if (contextId == INVALID_ID || agentId == INVALID_ID) {
1031             lock.unlock();
1032             SHARING_LOGE("connected, create sink agent failed, devMac: %{private}s.",
1033                          GetAnonyString(connectionInfo.mac).c_str());
1034             return;
1035         } else {
1036             SHARING_LOGI("connected, create sink agent, contextId: %{public}u, "
1037                          "agentId: %{public}u, devMac: %{private}s, devIp: %{private}s.",
1038                          contextId, agentId, connectionInfo.mac.c_str(), connectionInfo.ip.c_str());
1039         }
1040 
1041         connectionInfo.contextId = contextId;
1042         connectionInfo.agentId = agentId;
1043         connectionInfo.videoCodecId = videoCodecId_;
1044         connectionInfo.videoFormatId = videoFormatId_;
1045         connectionInfo.audioCodecId = audioCodecId_;
1046         connectionInfo.audioFormatId = audioFormatId_;
1047 
1048         std::shared_ptr<ConnectionInfo> connectionInfoPtr = std::make_shared<ConnectionInfo>(connectionInfo);
1049         devConnectionMap_.emplace(connectionInfo.mac, connectionInfoPtr);
1050         SHARING_LOGI("connected, devMac: %{private}s, devIp: %{private}s.", GetAnonyString(connectionInfo.mac).c_str(),
1051                      GetAnonyString(connectionInfo.ip).c_str());
1052     }
1053 
1054     OnConnectionChanged(connectionInfo);
1055 }
1056 
OnP2pPeerDisconnected(ConnectionInfo & connectionInfo)1057 void WfdSinkScene::OnP2pPeerDisconnected(ConnectionInfo &connectionInfo)
1058 {
1059     SHARING_LOGD("trace.");
1060     auto sharingAdapter = sharingAdapter_.lock();
1061     RETURN_IF_NULL(sharingAdapter);
1062 
1063     uint32_t contextId = INVALID_ID;
1064     uint32_t agentId = INVALID_ID;
1065     {
1066         std::unique_lock<std::mutex> lock(mutex_);
1067         auto itemDev = devConnectionMap_.find(connectionInfo.mac);
1068         if (itemDev == devConnectionMap_.end()) {
1069             lock.unlock();
1070             SHARING_LOGW("can not find dev, mac: %{private}s.", GetAnonyString(connectionInfo.mac).c_str());
1071             return;
1072         }
1073 
1074         contextId = itemDev->second->contextId;
1075         agentId = itemDev->second->agentId;
1076         connectionInfo.surfaceId = itemDev->second->surfaceId;
1077 
1078         for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1079             if (connectionInfo.mac == itemSurface->second->deviceId) {
1080                 itemSurface->second->deleting = true;
1081             }
1082             itemSurface++;
1083         }
1084 
1085         P2pRemoveClient(connectionInfo);
1086 
1087         devConnectionMap_.erase(connectionInfo.mac);
1088         SHARING_LOGI("disconnected, contextId: %{public}u, agentId: %{public}u, devMac: %{private}s.", contextId,
1089                      agentId, connectionInfo.mac.c_str());
1090     }
1091 
1092     OnConnectionChanged(connectionInfo);
1093 
1094     if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1095         return;
1096     }
1097 
1098     auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
1099     sessionMsg->type = EVENT_SESSION_TEARDOWN;
1100     sessionMsg->toMgr = MODULE_CONTEXT;
1101     sessionMsg->dstId = contextId;
1102     sessionMsg->agentId = agentId;
1103 
1104     SharingEvent event;
1105     event.eventMsg = std::move(sessionMsg);
1106 
1107     sharingAdapter->ForwardEvent(contextId, agentId, event, true);
1108     sharingAdapter->DestroyAgent(contextId, agentId);
1109 }
1110 
OnP2pPeerDisconnected(std::string & mac)1111 void WfdSinkScene::OnP2pPeerDisconnected(std::string &mac)
1112 {
1113     SHARING_LOGD("trace.");
1114     uint32_t contextId = INVALID_ID;
1115     uint32_t agentId = INVALID_ID;
1116     std::shared_ptr<ConnectionInfo> connectionInfo = nullptr;
1117     {
1118         std::unique_lock<std::mutex> lock(mutex_);
1119         auto itemDev = devConnectionMap_.find(mac);
1120         if (itemDev == devConnectionMap_.end()) {
1121             lock.unlock();
1122             SHARING_LOGW("can not find dev, mac: %{private}s.", GetAnonyString(mac).c_str());
1123             return;
1124         }
1125 
1126         contextId = itemDev->second->contextId;
1127         agentId = itemDev->second->agentId;
1128         connectionInfo = itemDev->second;
1129 
1130         for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1131             if (mac == itemSurface->second->deviceId) {
1132                 itemSurface->second->deleting = true;
1133             }
1134             itemSurface++;
1135         }
1136 
1137         SHARING_LOGI("disconnected, contextId: %{public}u, agentId: %{public}u, devMac: %{private}s.", contextId,
1138                      agentId, mac.c_str());
1139         P2pRemoveClient(*connectionInfo);
1140 
1141         devConnectionMap_.erase(mac);
1142     }
1143 
1144     if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1145         return;
1146     }
1147 
1148     auto sharingAdapter = sharingAdapter_.lock();
1149     if (sharingAdapter != nullptr) {
1150         sharingAdapter->DestroyAgent(contextId, agentId);
1151     }
1152 
1153     if (connectionInfo != nullptr) {
1154         connectionInfo->state = ConnectionState::DISCONNECTED;
1155         OnConnectionChanged(*connectionInfo);
1156     }
1157 }
1158 
ErrorCodeFiltering(int32_t & code)1159 void WfdSinkScene::ErrorCodeFiltering(int32_t &code)
1160 {
1161     SHARING_LOGD("the error code is %{public}d.", code);
1162     switch (ABSTRACT_ERR_BASE(code)) {
1163         case SharingErrorCode::ERR_CONTEXT_AGENT_BASE: // fall-through
1164         case SharingErrorCode::ERR_SESSION_BASE:
1165             code = SharingErrorCode::ERR_GENERAL_ERROR;
1166             SHARING_LOGD("the error change to %{public}d.", code);
1167             break;
1168         case SharingErrorCode::ERR_PROSUMER_BASE: {
1169             switch (code) {
1170                 case ERR_PROSUMER_START:
1171                     code = SharingErrorCode::ERR_CONNECTION_FAILURE;
1172                     break;
1173                 case ERR_PROSUMER_TIMEOUT:
1174                     code = SharingErrorCode::ERR_CONNECTION_TIMEOUT;
1175                     break;
1176                 case ERR_PROSUMER_DESTROY:
1177                     code = SharingErrorCode::ERR_STATE_EXCEPTION;
1178                     break;
1179                 default:
1180                     code = SharingErrorCode::ERR_GENERAL_ERROR;
1181                     break;
1182             }
1183             break;
1184         }
1185         default:
1186             SHARING_LOGI("none process case.");
1187             break;
1188     }
1189 }
1190 
OnInnerError(uint32_t contextId,uint32_t agentId,SharingErrorCode errorCode,std::string message)1191 void WfdSinkScene::OnInnerError(uint32_t contextId, uint32_t agentId, SharingErrorCode errorCode, std::string message)
1192 {
1193     SHARING_LOGD("trace.");
1194     auto ipcAdapter = ipcAdapter_.lock();
1195     RETURN_IF_NULL(ipcAdapter);
1196 
1197     auto msg = std::make_shared<WfdErrorMsg>();
1198     msg->contextId = contextId;
1199     msg->agentId = agentId;
1200     msg->errorCode = errorCode;
1201 
1202     for (auto &item : devConnectionMap_) {
1203         if ((contextId == item.second->contextId) && (agentId == item.second->agentId)) {
1204             msg->mac = item.second->mac;
1205             break;
1206         }
1207     }
1208 
1209     if (errorCode == SharingErrorCode::ERR_PROSUMER_TIMEOUT) {
1210         msg->message =
1211             "contextId: " + std::to_string(contextId) + ", agentId: " + std::to_string(agentId) + ", producer timeout";
1212     } else {
1213         msg->message = std::move(message);
1214     }
1215 
1216     ErrorCodeFiltering(msg->errorCode);
1217     auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1218 
1219     SHARING_LOGW("receive errorCode: %{public}d.", errorCode);
1220     ipcAdapter->SendRequest(msg, reply);
1221 }
1222 
OnInnerError(std::string deviceId,SharingErrorCode errorCode,std::string message)1223 void WfdSinkScene::OnInnerError(std::string deviceId, SharingErrorCode errorCode, std::string message)
1224 {
1225     SHARING_LOGD("trace.");
1226     auto ipcAdapter = ipcAdapter_.lock();
1227     RETURN_IF_NULL(ipcAdapter);
1228 
1229     auto msg = std::make_shared<WfdErrorMsg>();
1230     msg->message = message;
1231     msg->mac = deviceId;
1232     msg->errorCode = errorCode;
1233 
1234     auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1235 
1236     SHARING_LOGW("receive errorCode: %{public}d.", errorCode);
1237     ipcAdapter->SendRequest(msg, reply);
1238 }
1239 
OnInnerDestroy(uint32_t contextId,uint32_t agentId,AgentType agentType)1240 void WfdSinkScene::OnInnerDestroy(uint32_t contextId, uint32_t agentId, AgentType agentType)
1241 {
1242     SHARING_LOGI("HandleInnerDestroy, contextId: %{public}u, agentId: %{public}u, agentType: %{public}s.", contextId,
1243                  agentId, std::string(magic_enum::enum_name(agentType)).c_str());
1244 
1245     std::unique_lock<std::mutex> lock(mutex_);
1246     for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1247         if ((itemSurface->second != nullptr) && (contextId == itemSurface->second->contextId) &&
1248             (agentId == itemSurface->second->agentId)) {
1249             devSurfaceItemMap_.erase(itemSurface++);
1250         } else {
1251             itemSurface++;
1252         }
1253     }
1254 
1255     for (auto &item : devConnectionMap_) {
1256         if ((item.second != nullptr) && (contextId == item.second->contextId) && (agentId == item.second->agentId)) {
1257             ConnectionInfo connectionInfo;
1258             connectionInfo.ip = item.second->ip;
1259             connectionInfo.mac = item.second->mac;
1260             connectionInfo.deviceName = item.second->deviceName;
1261             connectionInfo.primaryDeviceType = item.second->primaryDeviceType;
1262             connectionInfo.secondaryDeviceType = item.second->secondaryDeviceType;
1263             connectionInfo.ctrlPort = item.second->ctrlPort;
1264             connectionInfo.state = ConnectionState::DISCONNECTED;
1265 
1266             SHARING_LOGI(
1267                 "disconnected, contextId: %{public}u, agentId: %{public}u, devMac: %{private}s, devIp: %{private}s.",
1268                 contextId, agentId, connectionInfo.mac.c_str(), connectionInfo.ip.c_str());
1269             OnConnectionChanged(connectionInfo);
1270 
1271             P2pRemoveClient(connectionInfo);
1272 
1273             devConnectionMap_.erase(item.second->mac);
1274             break;
1275         }
1276     }
1277 }
1278 
OnInnerEvent(SharingEvent & event)1279 void WfdSinkScene::OnInnerEvent(SharingEvent &event)
1280 {
1281     SHARING_LOGD("trace.");
1282     RETURN_IF_NULL(event.eventMsg);
1283 
1284     SHARING_LOGI("eventType: %{public}s.", std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
1285     switch (event.eventMsg->type) {
1286         case EventType::EVENT_WFD_NOTIFY_RTSP_PLAYED: {
1287             auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
1288             if (msg) {
1289                 std::unique_lock<std::mutex> lock(mutex_);
1290                 auto itConnection = devConnectionMap_.find(msg->mac);
1291                 if (itConnection == devConnectionMap_.end()) {
1292                     SHARING_LOGD("can't find dev %{private}s.", msg->mac.c_str());
1293                     break;
1294                 }
1295 
1296                 itConnection->second->state = ConnectionState::PLAYING;
1297                 OnConnectionChanged(*itConnection->second);
1298             }
1299             break;
1300         }
1301         case EventType::EVENT_WFD_NOTIFY_RTSP_TEARDOWN: {
1302             auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
1303             if (msg) {
1304                 OnP2pPeerDisconnected(msg->mac);
1305             }
1306             break;
1307         }
1308         case EventType::EVENT_INTERACTION_ACCELERATION_DONE: {
1309             auto msg = ConvertEventMsg<InteractionEventMsg>(event);
1310             SHARING_LOGD("On acceleration done, contextId: %{public}d agentId: %{public}d.", msg->contextId,
1311                          msg->agentId);
1312             for (auto connectInfoPair : devConnectionMap_) {
1313                 if (connectInfoPair.second != nullptr && connectInfoPair.second->contextId == msg->contextId &&
1314                     connectInfoPair.second->agentId == msg->agentId) {
1315                     SHARING_LOGD("On acceleration done, device found.");
1316                     auto connectInfo = connectInfoPair.second;
1317                     connectInfo->surfaceId = msg->surfaceId;
1318 
1319                     OnDecoderAccelerationDone(*connectInfo);
1320                     break;
1321                 }
1322                 SHARING_LOGW("On acceleration done, device not found.");
1323             }
1324             break;
1325         }
1326         case EventType::EVENT_INTERACTION_STATE_REMOVE_SURFACE: {
1327             auto msg = ConvertEventMsg<InteractionEventMsg>(event);
1328             SHARING_LOGD("On state remove surface, agentId: %{public}d.", msg->agentId);
1329             std::unique_lock<std::mutex> lock(mutex_);
1330             devSurfaceItemMap_.erase(msg->surfaceId);
1331             break;
1332         }
1333         case EVENT_INTERACTION_DECODER_DIED: {
1334             auto msg = ConvertEventMsg<InteractionEventMsg>(event);
1335             auto surfaceItem = devSurfaceItemMap_.find(msg->surfaceId);
1336             if (surfaceItem != devSurfaceItemMap_.end() && surfaceItem->second != nullptr) {
1337                 auto itConnection = devConnectionMap_.find(surfaceItem->second->deviceId);
1338                 OnDecoderDied(*itConnection->second);
1339             }
1340             break;
1341         }
1342         default:
1343             SHARING_LOGI("none process case.");
1344             break;
1345     }
1346 }
1347 
OnConnectionChanged(ConnectionInfo & connectionInfo)1348 void WfdSinkScene::OnConnectionChanged(ConnectionInfo &connectionInfo)
1349 {
1350     SHARING_LOGD("trace.");
1351     auto ipcAdapter = ipcAdapter_.lock();
1352     RETURN_IF_NULL(ipcAdapter);
1353 
1354     auto msg = std::make_shared<WfdConnectionChangedMsg>();
1355     msg->ip = connectionInfo.ip;
1356     msg->mac = connectionInfo.mac;
1357     msg->state = connectionInfo.state;
1358     msg->surfaceId = connectionInfo.surfaceId;
1359     msg->deviceName = connectionInfo.deviceName;
1360     msg->primaryDeviceType = connectionInfo.primaryDeviceType;
1361     msg->secondaryDeviceType = connectionInfo.secondaryDeviceType;
1362 
1363     auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1364     ipcAdapter->SendRequest(msg, reply);
1365 }
1366 
P2pRemoveClient(ConnectionInfo & connectionInfo)1367 void WfdSinkScene::P2pRemoveClient(ConnectionInfo &connectionInfo)
1368 {
1369     SHARING_LOGI("p2p remove client: %{private}s.", GetAnonyString(connectionInfo.mac).c_str());
1370     if (!p2pInstance_) {
1371         SHARING_LOGE("p2p instance is null");
1372         return;
1373     }
1374 
1375     OHOS::Wifi::GcInfo info;
1376     info.mac = connectionInfo.mac;
1377     info.ip = connectionInfo.ip;
1378     info.host = connectionInfo.deviceName;
1379 
1380     p2pInstance_->RemoveGroupClient(info);
1381 }
1382 
OnDecoderAccelerationDone(ConnectionInfo & connectionInfo)1383 void WfdSinkScene::OnDecoderAccelerationDone(ConnectionInfo &connectionInfo)
1384 {
1385     SHARING_LOGD("trace.");
1386     auto ipcAdapter = ipcAdapter_.lock();
1387     RETURN_IF_NULL(ipcAdapter);
1388 
1389     auto msg = std::make_shared<WfdDecoderAccelerationDoneMsg>();
1390     msg->surfaceId = connectionInfo.surfaceId;
1391 
1392     auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1393     ipcAdapter->SendRequest(msg, reply);
1394     SHARING_LOGD("device ip: %{private}s, mac: %{private}s, state: %{public}s.",
1395                  GetAnonyString(connectionInfo.ip).c_str(), GetAnonyString(connectionInfo.mac).c_str(),
1396                  std::string(magic_enum::enum_name(connectionInfo.state)).c_str());
1397 }
1398 
OnDecoderDied(ConnectionInfo & connectionInfo)1399 void WfdSinkScene::OnDecoderDied(ConnectionInfo &connectionInfo)
1400 {
1401     SHARING_LOGD("trace.");
1402     auto ipcAdapter = ipcAdapter_.lock();
1403     RETURN_IF_NULL(ipcAdapter);
1404 
1405     auto msg = std::make_shared<WfdSurfaceFailureMsg>();
1406     msg->surfaceId = connectionInfo.surfaceId;
1407     auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1408     ipcAdapter->SendRequest(msg, reply);
1409 
1410     SHARING_LOGD("failed at device ip: %{private}s, mac: %{private}s, state: %{public}s.", connectionInfo.ip.c_str(),
1411                  connectionInfo.mac.c_str(), std::string(magic_enum::enum_name(connectionInfo.state)).c_str());
1412 }
1413 
OnRemoteDied()1414 void WfdSinkScene::OnRemoteDied()
1415 {
1416     SHARING_LOGD("trace.");
1417     auto sharingAdapter = sharingAdapter_.lock();
1418     if (sharingAdapter) {
1419         sharingAdapter->ReleaseScene(GetId());
1420     }
1421 }
1422 
1423 REGISTER_CLASS_REFLECTOR(WfdSinkScene);
1424 } // namespace Sharing
1425 } // namespace OHOS
1426