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 "iservice_registry.h"
25 #include "network/socket/socket_utils.h"
26 #include "kits/c/wifi_hid2d.h"
27 #include "system_ability_definition.h"
28 #include "utils/utils.h"
29 #include "wfd_session_def.h"
30
31 using namespace OHOS::DistributedHardware;
32 namespace OHOS {
33 namespace Sharing {
34 constexpr int P2P_LISTEN_INTERVAL = 500;
35 constexpr int P2P_LISTEN_PERIOD = 500;
36 constexpr int DM_MAX_NAME_LENGTH = 32;
37
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)38 void WfdSinkScene::WfdSystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
39 {
40 if (systemAbilityId == WIFI_DEVICE_ABILITY_ID) {
41 SHARING_LOGI("%{public}s, id is %{public}d.", __FUNCTION__, systemAbilityId);
42 auto scene = scene_.lock();
43 if (scene == nullptr) {
44 SHARING_LOGE("WfdSinkScene is null");
45 return;
46 }
47 scene->OnWifiAbilityResume();
48 }
49 }
50
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)51 void WfdSinkScene::WfdSystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
52 const std::string& deviceId)
53 {
54 if (systemAbilityId == WIFI_DEVICE_ABILITY_ID) {
55 SHARING_LOGI("%{public}s, id is %{public}d.", __FUNCTION__, systemAbilityId);
56 auto scene = scene_.lock();
57 if (scene == nullptr) {
58 SHARING_LOGE("WfdSinkScene is null");
59 return;
60 }
61 scene->OnWifiAbilityDied();
62 }
63 }
64
OnP2pStateChanged(int32_t state)65 void WfdSinkScene::WfdP2pCallback::OnP2pStateChanged(int32_t state)
66 {
67 SHARING_LOGI("state: %{public}d.", state);
68 auto parent = parent_.lock();
69 if (parent) {
70 switch (state) {
71 case (int32_t)Wifi::P2pState::P2P_STATE_NONE:
72 break;
73 case (int32_t)Wifi::P2pState::P2P_STATE_IDLE:
74 break;
75 case (int32_t)Wifi::P2pState::P2P_STATE_STARTING:
76 break;
77 case (int32_t)Wifi::P2pState::P2P_STATE_STARTED:
78 if (parent->isSinkRunning_) {
79 parent->WfdP2pStart();
80 }
81 break;
82 case (int32_t)Wifi::P2pState::P2P_STATE_CLOSING:
83 break;
84 case (int32_t)Wifi::P2pState::P2P_STATE_CLOSED:
85 if (parent->isSinkRunning_) {
86 parent->isSinkRunning_ = false;
87 parent->WfdP2pStop();
88 parent->OnInnerError("", SharingErrorCode::ERR_NETWORK_ERROR, "NETWORK ERROR, P2P MODULE STOPPED");
89 WfdSinkHiSysEvent::GetInstance().P2PReportError(__func__,
90 SinkErrorCode::WIFI_DISPLAY_P2P_DISCONNECTED_STATE_CLOSED);
91 }
92 break;
93 default:
94 SHARING_LOGI("none process case.");
95 break;
96 }
97 }
98 }
99
OnP2pPersistentGroupsChanged(void)100 void WfdSinkScene::WfdP2pCallback::OnP2pPersistentGroupsChanged(void)
101 {
102 SHARING_LOGD("trace.");
103 }
104
OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice & device)105 void WfdSinkScene::WfdP2pCallback::OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice &device)
106 {
107 SHARING_LOGD("trace.");
108 }
109
OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> & device)110 void WfdSinkScene::WfdP2pCallback::OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> &device)
111 {
112 SHARING_LOGD("trace.");
113 auto parent = parent_.lock();
114 if (parent) {
115 SHARING_LOGI("device size: %{public}zu.", device.size());
116 for (auto itDev : device) {
117 auto status = itDev.GetP2pDeviceStatus();
118 SHARING_LOGI("device mac: %{public}s, status: %{public}d.",
119 GetAnonymousMAC(itDev.GetDeviceAddress()).c_str(), status);
120 switch (status) {
121 case Wifi::P2pDeviceStatus::PDS_AVAILABLE: {
122 ConnectionInfo connectionInfo;
123 connectionInfo.mac = itDev.GetDeviceAddress();
124 connectionInfo.deviceName = itDev.GetDeviceName();
125 connectionInfo.primaryDeviceType = itDev.GetPrimaryDeviceType();
126 connectionInfo.secondaryDeviceType = itDev.GetSecondaryDeviceType();
127 connectionInfo.ctrlPort = itDev.GetWfdInfo().GetCtrlPort();
128 connectionInfo.state = ConnectionState::DISCONNECTED;
129
130 parent->OnP2pPeerDisconnected(connectionInfo);
131 break;
132 }
133 case Wifi::P2pDeviceStatus::PDS_CONNECTED: {
134 std::unique_lock<std::mutex> lock(parent->currentConnectDevMutex_);
135 parent->currentConnectDev_.mac = itDev.GetDeviceAddress();
136 parent->currentConnectDev_.deviceName = itDev.GetDeviceName();
137 parent->currentConnectDev_.primaryDeviceType = itDev.GetPrimaryDeviceType();
138 parent->currentConnectDev_.secondaryDeviceType = itDev.GetSecondaryDeviceType();
139 parent->currentConnectDev_.ctrlPort = itDev.GetWfdInfo().GetCtrlPort();
140 parent->currentConnectDev_.ip = "";
141 parent->currentConnectDev_.state = ConnectionState::CONNECTED;
142 break;
143 }
144 default:
145 SHARING_LOGI("none process case.");
146 break;
147 }
148 }
149 }
150 }
151
OnP2pPrivatePeersChanged(const std::string & priWfdInfo)152 void WfdSinkScene::WfdP2pCallback::OnP2pPrivatePeersChanged(const std::string &priWfdInfo)
153 {
154 SHARING_LOGD("trace.");
155 }
156
OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> & srvInfo)157 void WfdSinkScene::WfdP2pCallback::OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> &srvInfo)
158 {
159 SHARING_LOGD("trace.");
160 }
161
162
OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo & info)163 void WfdSinkScene::WfdP2pCallback::OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo &info)
164 {
165 SHARING_LOGI("trace");
166 auto parent = parent_.lock();
167 RETURN_IF_NULL(parent);
168 if (!parent->isSinkRunning_) {
169 return;
170 }
171
172 Wifi::P2pConnectedState state = info.GetConnectState();
173 if (state == Wifi::P2pConnectedState::P2P_DISCONNECTED) {
174 SHARING_LOGI("OnP2pConnectionChanged disconnected");
175 std::string mac;
176 {
177 std::unique_lock<std::mutex> lock(parent->currentConnectDevMutex_);
178 mac = parent->currentConnectDev_.mac;
179 }
180 if (mac != "") {
181 parent->OnP2pPeerDisconnected(mac);
182 }
183 {
184 std::unique_lock<std::mutex> lock(parent->localIpMutex_);
185 parent->localIp_ = "";
186 }
187 parent->WfdP2pStart();
188 return;
189 }
190
191 parent->p2pInstance_->StopP2pListen();
192 Wifi::WifiP2pGroupInfo group;
193 if (Wifi::ErrCode::WIFI_OPT_SUCCESS != parent->p2pInstance_->GetCurrentGroup(group)) {
194 SHARING_LOGE("GetCurrentGroup failed");
195 return;
196 }
197 SHARING_LOGI("group frequency %{public}d", group.GetFrequency());
198 if (info.IsGroupOwner()) {
199 SHARING_LOGI("sink is go");
200 std::unique_lock<std::mutex> lock(parent->localIpMutex_);
201 parent->localIp_ = info.GetGroupOwnerAddress();
202 return;
203 } else {
204 SHARING_LOGI("sink is gc");
205 std::string remoteIp = info.GetGroupOwnerAddress();
206 if (remoteIp == "" || remoteIp == "0.0.0.0") {
207 SHARING_LOGE("get remoteIp ip failed");
208 return;
209 }
210 {
211 std::unique_lock<std::mutex> lock(parent->currentConnectDevMutex_);
212 parent->currentConnectDev_.ip = remoteIp;
213 }
214 std::string interface = group.GetInterface();
215 {
216 std::unique_lock<std::mutex> lock(parent->localIpMutex_);
217 parent->localIp_ = GetLocalP2pAddress(interface);
218 if (parent->localIp_.empty()) {
219 SHARING_LOGW("get local ip failed");
220 return;
221 }
222 }
223 wfdTrustListManager_.AddBoundDevice(group);
224 }
225 ConnectionInfo currentConnectDev;
226 {
227 std::unique_lock<std::mutex> lock(parent->currentConnectDevMutex_);
228 currentConnectDev = parent->currentConnectDev_;
229 }
230 parent->OnP2pPeerConnected(currentConnectDev);
231 std::unique_lock<std::mutex> lock(parent->currentConnectDevMutex_);
232 parent->currentConnectDev_ = currentConnectDev;
233 }
234
OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo & info)235 void WfdSinkScene::WfdP2pCallback::OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo &info)
236 {
237 SHARING_LOGI("trace.");
238 auto parent = parent_.lock();
239 if (parent && parent->p2pInstance_) {
240 std::vector<Wifi::WifiP2pDevice> devices;
241 if (Wifi::ErrCode::WIFI_OPT_SUCCESS != parent->p2pInstance_->QueryP2pDevices(devices)) {
242 SHARING_LOGE("QueryP2pDevices failed");
243 return;
244 }
245 SHARING_LOGI("QueryP2pDevices ip:%{private}s addr: %{private}s host: %{private}s.",
246 GetAnonymousIp(info.ip).c_str(), GetAnonymousMAC(info.mac).c_str(),
247 GetAnonyString(info.host).c_str());
248 if (info.ip == "0.0.0.0" || info.ip == "") {
249 SHARING_LOGE("device: %{private}s leased ip is: 0.0.0.0.", GetAnonymousMAC(info.mac).c_str());
250 parent->OnInnerError(info.mac.c_str(), ERR_P2P_DHCP_INVALID_IP, "ip is: 0.0.0.0.");
251 return;
252 }
253
254 for (auto itDev : devices) {
255 if (itDev.GetDeviceAddress() != info.mac) {
256 continue;
257 }
258 ConnectionInfo connectionInfo;
259 connectionInfo.ip = info.ip;
260 connectionInfo.mac = itDev.GetDeviceAddress();
261 connectionInfo.primaryDeviceType = itDev.GetPrimaryDeviceType();
262 connectionInfo.secondaryDeviceType = itDev.GetSecondaryDeviceType();
263 connectionInfo.ctrlPort = itDev.GetWfdInfo().GetCtrlPort();
264 connectionInfo.deviceName = itDev.GetDeviceName();
265 connectionInfo.state = ConnectionState::CONNECTED;
266 {
267 std::unique_lock<std::mutex> lock(parent->currentConnectDevMutex_);
268 parent->currentConnectDev_ = connectionInfo;
269 }
270 SHARING_LOGD("device connected, mac: %{private}s, ip: %{private}s, port: %{private}d",
271 GetAnonymousMAC(connectionInfo.mac).c_str(), GetAnonymousIp(connectionInfo.ip).c_str(),
272 connectionInfo.ctrlPort);
273 parent->OnP2pPeerConnected(connectionInfo);
274 Wifi::WifiP2pGroupInfo group;
275 parent->p2pInstance_->GetCurrentGroup(group);
276 wfdTrustListManager_.AddBoundDevice(group);
277 return;
278 }
279 }
280 }
281
OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo & info)282 void WfdSinkScene::WfdP2pCallback::OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo &info)
283 {
284 SHARING_LOGD("trace.");
285 }
286
OnP2pDiscoveryChanged(bool isChange)287 void WfdSinkScene::WfdP2pCallback::OnP2pDiscoveryChanged(bool isChange)
288 {
289 SHARING_LOGD("isChange: %{public}d.", isChange);
290 }
291
292 std::unordered_map<Wifi::ErrCode, SinkErrorCode> WfdSinkScene::WfdP2pCallback::wifiErrorMapping_ = {
293 { Wifi::WIFI_OPT_FAILED, SinkErrorCode::WIFI_DISPLAY_P2P_FAILED },
294 { Wifi::WIFI_OPT_NOT_SUPPORTED, SinkErrorCode::WIFI_DISPLAY_P2P_OPT_NOT_SUPPORTED },
295 { Wifi::WIFI_OPT_INVALID_PARAM, SinkErrorCode::WIFI_DISPLAY_P2P_OPT_INVALID_PARAM },
296 { Wifi::WIFI_OPT_FORBID_AIRPLANE, SinkErrorCode::WIFI_DISPLAY_P2P_OPT_FORBID_AIRPLANE },
297 { Wifi::WIFI_OPT_FORBID_POWSAVING, SinkErrorCode::WIFI_DISPLAY_P2P_OPT_FORBID_POWSAVING },
298 { Wifi::WIFI_OPT_PERMISSION_DENIED, SinkErrorCode::WIFI_DISPLAY_P2P_OPT_PERMISSION_DENIED },
299 { Wifi::WIFI_OPT_OPEN_FAIL_WHEN_CLOSING, SinkErrorCode::WIFI_DISPLAY_P2P_OPT_OPEN_FAIL_WHEN_CLOSING },
300 { Wifi::WIFI_OPT_P2P_NOT_OPENED, SinkErrorCode::WIFI_DISPLAY_P2P_OPT_P2P_NOT_OPENED },
301 };
302
GetErrorCode(Wifi::ErrCode errorCode,SinkErrorCode & sharingError)303 bool WfdSinkScene::WfdP2pCallback::GetErrorCode(Wifi::ErrCode errorCode, SinkErrorCode &sharingError)
304 {
305 auto it = wifiErrorMapping_.find(errorCode);
306 if (it != wifiErrorMapping_.end()) {
307 sharingError = it->second;
308 SHARING_LOGI("wifi errorCode: %{public}d, sharingError:%{public}d", errorCode, sharingError);
309 return true;
310 } else {
311 SHARING_LOGI("unknow wifi errorCode: %{public}d", errorCode);
312 return false;
313 }
314 }
315
OnP2pActionResult(Wifi::P2pActionCallback action,Wifi::ErrCode code)316 void WfdSinkScene::WfdP2pCallback::OnP2pActionResult(Wifi::P2pActionCallback action, Wifi::ErrCode code)
317 {
318 SHARING_LOGI("action %{public}hhu, code %{public}d", action, code);
319 auto parent = parent_.lock();
320 if (parent) {
321 SinkErrorCode sharingErrorCode;
322 if (code != Wifi::WIFI_OPT_SUCCESS) {
323 if (GetErrorCode(code, sharingErrorCode)) {
324 SHARING_LOGI("wifi errorCode: %{public}d, sharingErrorCode:%{public}d", code, sharingErrorCode);
325 WfdSinkHiSysEvent::GetInstance().P2PReportError(__func__, sharingErrorCode);
326 } else {
327 SHARING_LOGI("default return action %{public}hhu, code %{public}d", action, code);
328 WfdSinkHiSysEvent::GetInstance().P2PReportError(__func__, SinkErrorCode::WIFI_DISPLAY_P2P_FAILED);
329 }
330 }
331 }
332 }
333
OnConfigChanged(Wifi::CfgType type,char * data,int32_t dataLen)334 void WfdSinkScene::WfdP2pCallback::OnConfigChanged(Wifi::CfgType type, char *data, int32_t dataLen)
335 {
336 SHARING_LOGD("trace.");
337 }
338
OnP2pChrErrCodeReport(const int errCode)339 void WfdSinkScene::WfdP2pCallback::OnP2pChrErrCodeReport(const int errCode)
340 {
341 SHARING_LOGD("trace.");
342 }
343
OnWifiStateChanged(int state)344 void WfdSinkScene::WifiCallback::OnWifiStateChanged(int state)
345 {
346 SHARING_LOGI("OnWifiStateChanged state %{public}d", state);
347 if (state == static_cast<int32_t>(Wifi::WifiState::ENABLED)) {
348 auto parent = parent_.lock();
349 if (parent && parent->isSinkRunning_) {
350 parent->WfdP2pStart();
351 }
352 }
353 }
354
OnWifiConnectionChanged(int state,const OHOS::Wifi::WifiLinkedInfo & info)355 void WfdSinkScene::WifiCallback::OnWifiConnectionChanged(int state, const OHOS::Wifi::WifiLinkedInfo &info)
356 {
357 SHARING_LOGI("OnWifiConnectionChanged state %{public}d", state);
358 if (state == static_cast<int32_t>(Wifi::ConnState::CONNECTED) ||
359 state == static_cast<int32_t>(Wifi::ConnState::DISCONNECTED)) {
360 auto parent = parent_.lock();
361 if (!parent) {
362 return;
363 }
364 std::string mac;
365 {
366 std::unique_lock<std::mutex> lock(parent->currentConnectDevMutex_);
367 mac = parent->currentConnectDev_.mac;
368 }
369 if (parent->isSinkRunning_ && mac == "") {
370 parent->WfdP2pStart();
371 }
372 }
373 }
374
OnWifiRssiChanged(int rssi)375 void WfdSinkScene::WifiCallback::OnWifiRssiChanged(int rssi)
376 {
377 SHARING_LOGD("trace.");
378 }
379
OnWifiWpsStateChanged(int state,const std::string & pinCode)380 void WfdSinkScene::WifiCallback::OnWifiWpsStateChanged(int state, const std::string &pinCode)
381 {
382 SHARING_LOGD("trace.");
383 }
384
OnStreamChanged(int direction)385 void WfdSinkScene::WifiCallback::OnStreamChanged(int direction)
386 {
387 SHARING_LOGD("trace.");
388 }
389
OnDeviceConfigChanged(OHOS::Wifi::ConfigChange value)390 void WfdSinkScene::WifiCallback::OnDeviceConfigChanged(OHOS::Wifi::ConfigChange value)
391 {
392 SHARING_LOGD("trace.");
393 }
394
OnChange()395 void WfdSinkScene::DeviceNameObserver::OnChange()
396 {
397 SHARING_LOGI("deviceName observer onChange");
398 auto scene = scene_.lock();
399 if (scene && scene->isSinkRunning_) {
400 scene->InitP2pName();
401 }
402 }
403
WfdSinkScene()404 WfdSinkScene::WfdSinkScene()
405 {
406 SHARING_LOGI("id: %{public}u.", GetId());
407 currentConnectDev_.state = ConnectionState::DISCONNECTED;
408 }
409
~WfdSinkScene()410 WfdSinkScene::~WfdSinkScene()
411 {
412 SHARING_LOGI("id: %{public}u.", GetId());
413 Release();
414 }
415
Initialize()416 void WfdSinkScene::Initialize()
417 {
418 SHARING_LOGD("trace.");
419 SharingValue::Ptr values = nullptr;
420
421 auto ret = Config::GetInstance().GetConfig("sharingWfd", "ctrlport", "defaultWfdCtrlport", values);
422 if (ret == CONFIGURE_ERROR_NONE) {
423 values->GetValue<int32_t>(ctrlPort_);
424 }
425
426 ret = Config::GetInstance().GetConfig("sharingWfd", "abilityLimit", "accessDevMaximum", values);
427 if (ret == CONFIGURE_ERROR_NONE) {
428 values->GetValue<int32_t>(accessDevMaximum_);
429 }
430
431 ret = Config::GetInstance().GetConfig("sharingWfd", "abilityLimit", "surfaceMaximum", values);
432 if (ret == CONFIGURE_ERROR_NONE) {
433 values->GetValue<int32_t>(surfaceMaximum_);
434 }
435
436 ret = Config::GetInstance().GetConfig("sharingWfd", "abilityLimit", "foregroundMaximum", values);
437 if (ret == CONFIGURE_ERROR_NONE) {
438 values->GetValue<int32_t>(foregroundMaximum_);
439 }
440
441 ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "videoCodec", values);
442 if (ret == CONFIGURE_ERROR_NONE) {
443 int32_t videoCodec;
444 values->GetValue<int32_t>(videoCodec);
445 videoCodecId_ = static_cast<CodecId>(videoCodec);
446 }
447
448 ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "videoFormat", values);
449 if (ret == CONFIGURE_ERROR_NONE) {
450 int32_t videoFormat;
451 values->GetValue<int32_t>(videoFormat);
452 videoFormatId_ = static_cast<VideoFormat>(videoFormat);
453 }
454
455 ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "audioCodec", values);
456 if (ret == CONFIGURE_ERROR_NONE) {
457 int32_t audioCodec;
458 values->GetValue<int32_t>(audioCodec);
459 audioCodecId_ = static_cast<CodecId>(audioCodec);
460 }
461
462 ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "audioFormat", values);
463 if (ret == CONFIGURE_ERROR_NONE) {
464 int32_t audioFormat;
465 values->GetValue<int32_t>(audioFormat);
466 audioFormatId_ = static_cast<AudioFormat>(audioFormat);
467 }
468
469 RegisterP2pListener();
470 RegisterWifiStatusChangeListener();
471 RegisterDevNameObserver();
472 InitP2pName();
473 isInitialized_ = true;
474 RegisterWfdAbilityListener();
475 }
476
OnWifiAbilityResume()477 void WfdSinkScene::OnWifiAbilityResume()
478 {
479 SHARING_LOGI("%{public}s.", __FUNCTION__);
480 if (isInitialized_) {
481 return;
482 }
483 RegisterP2pListener();
484 RegisterWifiStatusChangeListener();
485 InitP2pName();
486 isInitialized_ = true;
487 }
488
OnWifiAbilityDied()489 void WfdSinkScene::OnWifiAbilityDied()
490 {
491 SHARING_LOGI("%{public}s.", __FUNCTION__);
492 std::string mac;
493 {
494 std::unique_lock<std::mutex> lock(currentConnectDevMutex_);
495 mac = currentConnectDev_.mac;
496 }
497 if (mac != "") {
498 OnP2pPeerDisconnected(mac);
499 }
500 isInitialized_ = false;
501 }
502
RegisterDevNameObserver()503 void WfdSinkScene::RegisterDevNameObserver()
504 {
505 SHARING_LOGI("RegisterDevNameObserver");
506 if (deviceNameObserver_ != nullptr) {
507 SHARING_LOGI("unregister old name observer");
508 UnRegisterDevNameObserver();
509 }
510
511 deviceNameObserver_ = new (std::nothrow) DeviceNameObserver(shared_from_this());
512 if (deviceNameObserver_ == nullptr) {
513 SHARING_LOGE("new deviceNameObserver error");
514 return;
515 }
516 int32_t ret = DataShareHelper::GetInstance().RegisterObserver(deviceNameObserver_);
517 SHARING_LOGI("register name observer ret=%{public}d", ret);
518 }
519
UnRegisterDevNameObserver()520 void WfdSinkScene::UnRegisterDevNameObserver()
521 {
522 int32_t ret = DataShareHelper::GetInstance().UnregisterObserver(deviceNameObserver_);
523 SHARING_LOGI("unregister name observer ret=%{public}d", ret);
524 deviceNameObserver_ = nullptr;
525 }
526
InitP2pName()527 void WfdSinkScene::InitP2pName()
528 {
529 DmKit::InitDeviceManager();
530 std::string deviceName;
531 if (DeviceManager::GetInstance().GetLocalDisplayDeviceName(DM_PKG_NAME, DM_MAX_NAME_LENGTH, deviceName) != DM_OK) {
532 SHARING_LOGW("getLocalDeviceInfo from dm failed");
533 } else {
534 if (p2pInstance_) {
535 p2pInstance_->SetP2pDeviceName(deviceName);
536 }
537 }
538 }
539
RegisterP2pListener()540 void WfdSinkScene::RegisterP2pListener()
541 {
542 p2pInstance_ = Wifi::WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
543 RETURN_IF_NULL(p2pInstance_);
544 sptr<WfdP2pCallback> wfdP2pCallback(new WfdP2pCallback(shared_from_this()));
545 std::vector<std::string> event = {EVENT_P2P_PEER_DEVICE_CHANGE, EVENT_P2P_CONN_STATE_CHANGE,
546 EVENT_P2P_GC_JOIN_GROUP, EVENT_P2P_GC_LEAVE_GROUP, EVENT_P2P_ACTION_RESULT};
547 p2pInstance_->RegisterCallBack(wfdP2pCallback, event);
548 }
549
RegisterWifiStatusChangeListener()550 void WfdSinkScene::RegisterWifiStatusChangeListener()
551 {
552 auto deviceInstance = Wifi::WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
553 RETURN_IF_NULL(deviceInstance);
554 auto callback = sptr<Wifi::IWifiDeviceCallBack> (new WifiCallback(shared_from_this()));
555 std::vector<std::string> events = {EVENT_STA_POWER_STATE_CHANGE, EVENT_STA_CONN_STATE_CHANGE};
556 deviceInstance->RegisterCallBack(callback, events);
557 }
558
Release()559 void WfdSinkScene::Release()
560 {
561 SHARING_LOGD("trace.");
562 UnRegisterWfdAbilityListener();
563 UnRegisterDevNameObserver();
564 std::unique_lock<std::mutex> lock(mutex_);
565 auto sharingAdapter = sharingAdapter_.lock();
566 if (sharingAdapter != nullptr) {
567 for (auto &item : devConnectionMap_) {
568 uint32_t contextId = INVALID_ID;
569 uint32_t agentId = INVALID_ID;
570 if (item.second == nullptr) {
571 continue;
572 }
573
574 contextId = item.second->contextId;
575 agentId = item.second->agentId;
576
577 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
578 continue;
579 }
580
581 auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
582 sessionMsg->type = EVENT_SESSION_TEARDOWN;
583 sessionMsg->toMgr = MODULE_CONTEXT;
584 sessionMsg->dstId = contextId;
585 sessionMsg->agentId = agentId;
586
587 SharingEvent event;
588 event.eventMsg = std::move(sessionMsg);
589 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
590
591 P2pRemoveClient(*(item.second));
592
593 sharingAdapter->DestroyAgent(contextId, agentId);
594 }
595 }
596
597 devConnectionMap_.clear();
598 devSurfaceItemMap_.clear();
599 p2pInstance_.reset();
600 }
601
OnDomainMsg(std::shared_ptr<BaseDomainMsg> & msg)602 void WfdSinkScene::OnDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)
603 {
604 SHARING_LOGD("trace.");
605 }
606
OnRequest(std::shared_ptr<BaseMsg> msg,std::shared_ptr<BaseMsg> & reply)607 void WfdSinkScene::OnRequest(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)
608 {
609 SHARING_LOGD("trace.");
610 RETURN_IF_NULL(msg);
611 SHARING_LOGI("recv msg, msg id: %{public}d.", msg->GetMsgId());
612 switch (msg->GetMsgId()) {
613 case WfdSinkStartReq::MSG_ID: {
614 auto data = std::static_pointer_cast<WfdSinkStartReq>(msg);
615 auto rsp = std::make_shared<WfdCommonRsp>();
616
617 rsp->ret = HandleStart(data, rsp);
618 reply = std::static_pointer_cast<BaseMsg>(rsp);
619 break;
620 }
621 case WfdSinkStopReq::MSG_ID: {
622 auto data = std::static_pointer_cast<WfdSinkStopReq>(msg);
623 auto rsp = std::make_shared<WfdCommonRsp>();
624
625 rsp->ret = HandleStop(data, rsp);
626 reply = std::static_pointer_cast<BaseMsg>(rsp);
627 break;
628 }
629 case WfdAppendSurfaceReq::MSG_ID: {
630 auto data = std::static_pointer_cast<WfdAppendSurfaceReq>(msg);
631 auto rsp = std::make_shared<WfdCommonRsp>();
632
633 rsp->ret = HandleAppendSurface(data, rsp);
634 reply = std::static_pointer_cast<BaseMsg>(rsp);
635 break;
636 }
637 case WfdRemoveSurfaceReq::MSG_ID: {
638 auto data = std::static_pointer_cast<WfdRemoveSurfaceReq>(msg);
639 auto rsp = std::make_shared<WfdCommonRsp>();
640
641 rsp->ret = HandleRemoveSurface(data, rsp);
642 reply = std::static_pointer_cast<BaseMsg>(rsp);
643 break;
644 }
645 case SetMediaFormatReq::MSG_ID: {
646 auto data = std::static_pointer_cast<SetMediaFormatReq>(msg);
647 auto rsp = std::make_shared<WfdCommonRsp>();
648
649 rsp->ret = HandleSetMediaFormat(data, rsp);
650 reply = std::static_pointer_cast<BaseMsg>(rsp);
651 break;
652 }
653 case SetSceneTypeReq::MSG_ID: {
654 auto data = std::static_pointer_cast<SetSceneTypeReq>(msg);
655 auto rsp = std::make_shared<WfdCommonRsp>();
656
657 rsp->ret = HandleSetSceneType(data, rsp);
658 reply = std::static_pointer_cast<BaseMsg>(rsp);
659 break;
660 }
661 case WfdPlayReq::MSG_ID: {
662 auto data = std::static_pointer_cast<WfdPlayReq>(msg);
663 auto rsp = std::make_shared<WfdCommonRsp>();
664
665 rsp->ret = HandlePlay(data, rsp);
666 reply = std::static_pointer_cast<BaseMsg>(rsp);
667 break;
668 }
669 case WfdPauseReq::MSG_ID: {
670 auto data = std::static_pointer_cast<WfdPauseReq>(msg);
671 auto rsp = std::make_shared<WfdCommonRsp>();
672
673 rsp->ret = HandlePause(data, rsp);
674 reply = std::static_pointer_cast<BaseMsg>(rsp);
675 break;
676 }
677 case MuteReq::MSG_ID: {
678 auto data = std::static_pointer_cast<MuteReq>(msg);
679 auto rsp = std::make_shared<WfdCommonRsp>();
680
681 rsp->ret = HandleMute(data, rsp);
682 reply = std::static_pointer_cast<BaseMsg>(rsp);
683 break;
684 }
685 case UnMuteReq::MSG_ID: {
686 auto data = std::static_pointer_cast<UnMuteReq>(msg);
687 auto rsp = std::make_shared<WfdCommonRsp>();
688
689 rsp->ret = HandleUnMute(data, rsp);
690 reply = std::static_pointer_cast<BaseMsg>(rsp);
691 break;
692 }
693 case WfdCloseReq::MSG_ID: {
694 auto data = std::static_pointer_cast<WfdCloseReq>(msg);
695 auto rsp = std::make_shared<WfdCommonRsp>();
696
697 rsp->ret = HandleClose(data, rsp);
698 reply = std::static_pointer_cast<BaseMsg>(rsp);
699 break;
700 }
701 case GetSinkConfigReq::MSG_ID: {
702 auto data = std::static_pointer_cast<GetSinkConfigReq>(msg);
703 auto rsp = std::make_shared<GetSinkConfigRsp>();
704
705 rsp->foregroundMaximum = INVALID_ID;
706 HandleGetConfig(data, rsp);
707 reply = std::static_pointer_cast<BaseMsg>(rsp);
708 break;
709 }
710 case WfdGetBoundDevicesReq::MSG_ID: {
711 auto data = std::static_pointer_cast<WfdGetBoundDevicesReq>(msg);
712 auto rsp = std::make_shared<WfdGetBoundDevicesRsp>();
713
714 HandleGetBoundDevices(data, rsp);
715 reply = std::static_pointer_cast<BaseMsg>(rsp);
716 break;
717 }
718 case WfdDeleteBoundDeviceReq::MSG_ID: {
719 auto data = std::static_pointer_cast<WfdDeleteBoundDeviceReq>(msg);
720 auto rsp = std::make_shared<WfdCommonRsp>();
721
722 HandleDeleteBoundDevice(data, rsp);
723 reply = std::static_pointer_cast<BaseMsg>(rsp);
724 break;
725 }
726 default:
727 SHARING_LOGW("unknown msg request.");
728 break;
729 }
730 }
731
SetWifiScene(uint32_t scene)732 void WfdSinkScene::SetWifiScene(uint32_t scene)
733 {
734 SHARING_LOGI("SetWifiScene %{public}u start", scene);
735 std::string ifName = "p2p0";
736 Hid2dUpperScene upperScene;
737 upperScene.scene = scene;
738 upperScene.fps = -1;
739 upperScene.bw = 0;
740 if (Hid2dSetUpperScene(ifName.c_str(), &upperScene) != 0) {
741 SHARING_LOGE("SetWifiScene scene: %{public}u error", scene);
742 }
743 SHARING_LOGI("SetWifiScene %{public}u over", scene);
744 }
745
HandleStart(std::shared_ptr<WfdSinkStartReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)746 int32_t WfdSinkScene::HandleStart(std::shared_ptr<WfdSinkStartReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
747 {
748 SHARING_LOGD("trace.");
749 (void)msg;
750 (void)reply;
751 if (isSinkRunning_) {
752 SHARING_LOGW("p2p sink is running.");
753 return 0;
754 }
755 RETURN_INVALID_IF_NULL(p2pInstance_);
756 int32_t ret = 0;
757 int32_t status = 0;
758 p2pInstance_->GetP2pEnableStatus(status);
759 switch (status) {
760 case (int32_t)Wifi::P2pState::P2P_STATE_NONE:
761 case (int32_t)Wifi::P2pState::P2P_STATE_IDLE:
762 case (int32_t)Wifi::P2pState::P2P_STATE_STARTING:
763 case (int32_t)Wifi::P2pState::P2P_STATE_CLOSING:
764 WfdSinkHiSysEvent::GetInstance().P2PReportError(__func__,
765 SinkErrorCode::WIFI_DISPLAY_P2P_DISCONNECTED_STATE_CLOSED);
766 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "HandleStart current p2p state: CLOSING");
767 ret = -1;
768 break;
769 case (int32_t)Wifi::P2pState::P2P_STATE_STARTED:
770 isSinkRunning_ = true;
771 WfdP2pStart();
772 break;
773 case (int32_t)Wifi::P2pState::P2P_STATE_CLOSED:
774 if (Wifi::ErrCode::WIFI_OPT_SUCCESS != p2pInstance_->EnableP2p()) {
775 SHARING_LOGE("EnableP2p failed");
776 return -1;
777 }
778 isSinkRunning_ = true;
779 WfdP2pStart();
780 break;
781 default:
782 SHARING_LOGI("none process case.");
783 break;
784 }
785
786 return ret;
787 }
788
HandleStop(std::shared_ptr<WfdSinkStopReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)789 int32_t WfdSinkScene::HandleStop(std::shared_ptr<WfdSinkStopReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
790 {
791 SHARING_LOGD("handle stop, now connect device num: %{public}zu.", devConnectionMap_.size());
792 (void)msg;
793 (void)reply;
794 if (!isSinkRunning_) {
795 SHARING_LOGW("p2p sink is not running.");
796 return -1;
797 }
798
799 isSinkRunning_ = false;
800 WfdP2pStop();
801
802 return 0;
803 }
804
HandleAppendSurface(std::shared_ptr<WfdAppendSurfaceReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)805 int32_t WfdSinkScene::HandleAppendSurface(std::shared_ptr<WfdAppendSurfaceReq> &msg,
806 std::shared_ptr<WfdCommonRsp> &reply)
807 {
808 SHARING_LOGD("trace.");
809 (void)reply;
810 RETURN_INVALID_IF_NULL(msg);
811 auto sharingAdapter = sharingAdapter_.lock();
812 RETURN_INVALID_IF_NULL(sharingAdapter);
813
814 {
815 std::unique_lock<std::mutex> lock(mutex_);
816 auto itemDev = devConnectionMap_.find(msg->deviceId);
817 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
818 lock.unlock();
819 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonymousMAC(msg->deviceId).c_str());
820 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleAppendSurface can't find the dev");
821 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::SESSION_NEGOTIATION,
822 SinkErrorCode::WIFI_DISPLAY_BAD_PARAMETER);
823 return -1;
824 }
825 int32_t surfaceNum = 0;
826 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
827 if (!itemSurface->second->deleting) {
828 surfaceNum++;
829 }
830 itemSurface++;
831 }
832
833 if (surfaceNum >= surfaceMaximum_) {
834 lock.unlock();
835 SHARING_LOGE("surface is too much.");
836 OnInnerError(0, 0, SharingErrorCode::ERR_SERVICE_LIMIT, "HandleAppendSurface surface is too much");
837 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::SESSION_NEGOTIATION,
838 SinkErrorCode::WIFI_DISPLAY_ADD_SURFACE_ERROR);
839 return -1;
840 }
841
842 sptr<IBufferProducer> producer = iface_cast<IBufferProducer>(msg->surface);
843 sptr<Surface> surfacePtr = Surface::CreateSurfaceAsProducer(producer);
844 if (surfacePtr == nullptr) {
845 SHARING_LOGE("invalid surface.");
846 return -1;
847 }
848
849 uint64_t surfaceId = surfacePtr->GetUniqueId();
850 SHARING_LOGI("get surfaceId %{public}" PRIx64 ".", surfaceId);
851 if (devSurfaceItemMap_.count(surfaceId)) {
852 SHARING_LOGW("this surface is using, surfaceId: %{public}" PRIx64 ".", surfaceId);
853 lock.unlock();
854 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "HandleAppendSurface this surface is using");
855 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::SESSION_NEGOTIATION,
856 SinkErrorCode::WIFI_DISPLAY_ADD_SURFACE_ERROR);
857 return ERR_STATE_EXCEPTION;
858 }
859
860 int32_t foregroundSurfaceNum = 0;
861 for (auto item : devSurfaceItemMap_) {
862 if ((item.second != nullptr) && (item.second->deviceId == msg->deviceId) && (!item.second->deleting)) {
863 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "Only one surface can be set.");
864 return ERR_STATE_EXCEPTION;
865 }
866
867 if (item.second != nullptr && item.second->sceneType == SceneType::FOREGROUND) {
868 foregroundSurfaceNum++;
869 }
870 }
871
872 auto devSurfaceItem = std::make_shared<DevSurfaceItem>();
873 devSurfaceItem->contextId = itemDev->second->contextId;
874 devSurfaceItem->agentId = itemDev->second->agentId;
875 devSurfaceItem->deviceId = itemDev->second->mac;
876 devSurfaceItem->surfacePtr = surfacePtr;
877 devSurfaceItem->sceneType = (foregroundSurfaceNum >= foregroundMaximum_) ? BACKGROUND : FOREGROUND;
878 devSurfaceItemMap_.emplace(surfaceId, devSurfaceItem);
879
880 if (itemDev->second->isRunning) {
881 uint32_t contextId = itemDev->second->contextId;
882 uint32_t agentId = itemDev->second->agentId;
883
884 auto startSessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
885 startSessionMsg->type = EVENT_WFD_REQUEST_IDR;
886 startSessionMsg->toMgr = MODULE_CONTEXT;
887 startSessionMsg->dstId = contextId;
888 startSessionMsg->agentId = agentId;
889
890 SharingEvent event;
891 event.eventMsg = std::move(startSessionMsg);
892 if (sharingAdapter) {
893 sharingAdapter->ForwardEvent(contextId, agentId, event, false);
894 sharingAdapter->AppendSurface(itemDev->second->contextId, itemDev->second->agentId, surfacePtr,
895 devSurfaceItem->sceneType);
896 }
897 itemDev->second->state = ConnectionState::PLAYING;
898 OnConnectionChanged(*itemDev->second);
899 }
900 }
901 return 0;
902 }
903
HandleRemoveSurface(std::shared_ptr<WfdRemoveSurfaceReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)904 int32_t WfdSinkScene::HandleRemoveSurface(std::shared_ptr<WfdRemoveSurfaceReq> &msg,
905 std::shared_ptr<WfdCommonRsp> &reply)
906 {
907 SHARING_LOGD("trace.");
908 (void)reply;
909 RETURN_INVALID_IF_NULL(msg);
910 auto sharingAdapter = sharingAdapter_.lock();
911 RETURN_INVALID_IF_NULL(sharingAdapter);
912 {
913 std::unique_lock<std::mutex> lock(mutex_);
914 auto itemDev = devConnectionMap_.find(msg->deviceId);
915 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
916 lock.unlock();
917 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonymousMAC(msg->deviceId).c_str());
918 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleRemoveSurface can't find the dev");
919 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::SESSION_NEGOTIATION,
920 SinkErrorCode::WIFI_DISPLAY_BAD_PARAMETER);
921 return -1;
922 }
923
924 auto item = devSurfaceItemMap_.find(msg->surfaceId);
925 if (item == devSurfaceItemMap_.end()) {
926 lock.unlock();
927 SHARING_LOGE("can not find surfaceid, surfaceid: %{public}" PRId64 ".", msg->surfaceId);
928 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleAppendSurface can't find the dev");
929 return -1;
930 }
931
932 SHARING_LOGW("del surface, surfaceid: %{public}" PRId64 ".", msg->surfaceId);
933 sharingAdapter->RemoveSurface(itemDev->second->contextId, itemDev->second->agentId, msg->surfaceId);
934 }
935
936 return 0;
937 }
938
HandleSetMediaFormat(std::shared_ptr<SetMediaFormatReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)939 int32_t WfdSinkScene::HandleSetMediaFormat(std::shared_ptr<SetMediaFormatReq> &msg,
940 std::shared_ptr<WfdCommonRsp> &reply)
941 {
942 SHARING_LOGD("trace.");
943 (void)reply;
944 RETURN_INVALID_IF_NULL(msg);
945 {
946 std::unique_lock<std::mutex> lock(mutex_);
947 auto itemDev = devConnectionMap_.find(msg->deviceId);
948 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
949 lock.unlock();
950 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonymousMAC(msg->deviceId).c_str());
951 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleSetMediaFormat can not find dev");
952 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::SESSION_NEGOTIATION,
953 SinkErrorCode::WIFI_DISPLAY_BAD_PARAMETER);
954 return -1;
955 }
956 itemDev->second->videoCodecId = static_cast<CodecId>(msg->videoAttr.codecType);
957 itemDev->second->videoFormatId = static_cast<VideoFormat>(msg->videoAttr.formatId);
958 itemDev->second->audioCodecId = static_cast<CodecId>(msg->audioAttr.codecType);
959 itemDev->second->audioFormatId = static_cast<AudioFormat>(msg->audioAttr.formatId);
960 }
961
962 return 0;
963 }
964
HandleSetSceneType(std::shared_ptr<SetSceneTypeReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)965 int32_t WfdSinkScene::HandleSetSceneType(std::shared_ptr<SetSceneTypeReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
966 {
967 SHARING_LOGD("trace.");
968 (void)reply;
969 RETURN_INVALID_IF_NULL(msg);
970 auto sharingAdapter = sharingAdapter_.lock();
971 RETURN_INVALID_IF_NULL(sharingAdapter);
972
973 uint32_t contextId = INVALID_ID;
974 uint32_t agentId = INVALID_ID;
975 {
976 std::unique_lock<std::mutex> lock(mutex_);
977 auto itemDev = devConnectionMap_.find(msg->deviceId);
978 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
979 lock.unlock();
980 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonymousMAC(msg->deviceId).c_str());
981 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleSetSceneType can not find dev");
982 return -1;
983 }
984
985 auto itemSurface = devSurfaceItemMap_.find(msg->surfaceId);
986 if (itemSurface == devSurfaceItemMap_.end() || itemSurface->second == nullptr
987 || itemSurface->second->deleting) {
988 lock.unlock();
989 SHARING_LOGE("can not find surfaceid, surfaceid: %{public}" PRId64 ".", msg->surfaceId);
990 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleSetSceneType can't find the surfaceId");
991 return -1;
992 }
993
994 contextId = itemDev->second->contextId;
995 agentId = itemDev->second->agentId;
996
997 uint32_t foregroundSurfaceNum = 1;
998 if (msg->sceneType == SceneType::FOREGROUND) {
999 for (auto item : devSurfaceItemMap_) {
1000 if ((item.first == msg->surfaceId) && (!item.second->deleting)) {
1001 continue;
1002 }
1003
1004 if (item.second->sceneType == SceneType::FOREGROUND) {
1005 foregroundSurfaceNum++;
1006 }
1007 }
1008
1009 if (foregroundSurfaceNum > static_cast<uint32_t>(foregroundMaximum_)) {
1010 lock.unlock();
1011 SHARING_LOGE("foreground surfaces is too much.");
1012 OnInnerError(0, 0, SharingErrorCode::ERR_SERVICE_LIMIT,
1013 "HandleSetSceneType foreground surfaces is too much");
1014 return -1;
1015 } else {
1016 itemSurface->second->sceneType = SceneType::FOREGROUND;
1017 }
1018 } else {
1019 itemSurface->second->sceneType = SceneType::BACKGROUND;
1020 }
1021 }
1022
1023 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1024 SHARING_LOGW("invalid contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
1025 return 0;
1026 }
1027
1028 bool keyFrame = msg->sceneType == SceneType::BACKGROUND ? true : false;
1029 auto ret = sharingAdapter->SetKeyPlay(contextId, agentId, msg->surfaceId, keyFrame);
1030 if (!keyFrame) {
1031 sharingAdapter->SetKeyRedirect(contextId, agentId, msg->surfaceId, true);
1032 }
1033
1034 return ret;
1035 }
1036
HandlePlay(std::shared_ptr<WfdPlayReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)1037 int32_t WfdSinkScene::HandlePlay(std::shared_ptr<WfdPlayReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
1038 {
1039 SHARING_LOGD("trace.");
1040 (void)reply;
1041 RETURN_INVALID_IF_NULL(msg);
1042 auto sharingAdapter = sharingAdapter_.lock();
1043 RETURN_INVALID_IF_NULL(sharingAdapter);
1044
1045 {
1046 std::unique_lock<std::mutex> lock(mutex_);
1047 auto itemDev = devConnectionMap_.find(msg->deviceId);
1048 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
1049 lock.unlock();
1050 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonymousMAC(msg->deviceId).c_str());
1051 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandlePlay can not find dev");
1052 return -1;
1053 }
1054
1055 uint32_t contextId = itemDev->second->contextId;
1056 uint32_t agentId = itemDev->second->agentId;
1057 if (contextId == INVALID_ID || agentId == INVALID_ID) {
1058 lock.unlock();
1059 SHARING_LOGE("connected, create sink agent failed, devMac: %{private}s.",
1060 GetAnonymousMAC(msg->deviceId).c_str());
1061 return -1;
1062 }
1063
1064 if (itemDev->second->isRunning == true) {
1065 lock.unlock();
1066 return sharingAdapter->Resume(contextId, agentId, MEDIA_TYPE_AV);
1067 } else {
1068 itemDev->second->isRunning = true;
1069 }
1070
1071 lock.unlock();
1072
1073 auto startSessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
1074 startSessionMsg->type = EVENT_SESSION_INIT;
1075 startSessionMsg->toMgr = MODULE_CONTEXT;
1076 startSessionMsg->dstId = contextId;
1077 startSessionMsg->agentId = agentId;
1078 startSessionMsg->remoteIp = itemDev->second->ip;
1079 {
1080 std::unique_lock<std::mutex> lock(localIpMutex_);
1081 startSessionMsg->localIp = localIp_;
1082 }
1083 startSessionMsg->mac = itemDev->second->mac;
1084 startSessionMsg->remotePort = itemDev->second->ctrlPort;
1085 startSessionMsg->videoFormat = itemDev->second->videoFormatId;
1086 startSessionMsg->audioFormat = itemDev->second->audioFormatId;
1087 startSessionMsg->localPort = SocketUtils::GetAvailableUdpPortPair();
1088 startSessionMsg->wfdParamsInfo = wfdParamsInfo_;
1089
1090 SharingEvent event;
1091 event.eventMsg = std::move(startSessionMsg);
1092
1093 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
1094 sharingAdapter->Start(contextId, agentId);
1095
1096 for (auto &item : devSurfaceItemMap_) {
1097 if ((item.second != nullptr) && (itemDev->first == item.second->deviceId) && (!item.second->deleting)) {
1098 if (item.second->surfacePtr != nullptr) {
1099 sharingAdapter->AppendSurface(contextId, agentId, item.second->surfacePtr, item.second->sceneType);
1100 }
1101 }
1102 }
1103
1104 sharingAdapter->Play(contextId, agentId);
1105 }
1106
1107 return 0;
1108 }
1109
HandlePause(std::shared_ptr<WfdPauseReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)1110 int32_t WfdSinkScene::HandlePause(std::shared_ptr<WfdPauseReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
1111 {
1112 SHARING_LOGD("trace.");
1113 (void)reply;
1114 RETURN_INVALID_IF_NULL(msg);
1115 auto sharingAdapter = sharingAdapter_.lock();
1116 RETURN_INVALID_IF_NULL(sharingAdapter);
1117
1118 uint32_t contextId = INVALID_ID;
1119 uint32_t agentId = INVALID_ID;
1120 {
1121 std::unique_lock<std::mutex> lock(mutex_);
1122 auto itemDev = devConnectionMap_.find(msg->deviceId);
1123 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
1124 lock.unlock();
1125 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonymousMAC(msg->deviceId).c_str());
1126 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandlePause can not find dev");
1127 return -1;
1128 }
1129
1130 contextId = itemDev->second->contextId;
1131 agentId = itemDev->second->agentId;
1132 }
1133
1134 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1135 return -1;
1136 }
1137
1138 return sharingAdapter->Pause(contextId, agentId, MEDIA_TYPE_AV);
1139 }
1140
HandleMute(std::shared_ptr<MuteReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)1141 int32_t WfdSinkScene::HandleMute(std::shared_ptr<MuteReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
1142 {
1143 SHARING_LOGD("trace.");
1144 (void)reply;
1145 RETURN_INVALID_IF_NULL(msg);
1146 auto sharingAdapter = sharingAdapter_.lock();
1147 RETURN_INVALID_IF_NULL(sharingAdapter);
1148
1149 uint32_t contextId = INVALID_ID;
1150 uint32_t agentId = INVALID_ID;
1151 {
1152 std::unique_lock<std::mutex> lock(mutex_);
1153 auto itemDev = devConnectionMap_.find(msg->deviceId);
1154 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
1155 lock.unlock();
1156 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonymousMAC(msg->deviceId).c_str());
1157 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleMute can not find dev");
1158 return -1;
1159 }
1160
1161 contextId = itemDev->second->contextId;
1162 agentId = itemDev->second->agentId;
1163 }
1164
1165 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1166 return -1;
1167 }
1168
1169 return sharingAdapter->Pause(contextId, agentId, MEDIA_TYPE_AUDIO);
1170 }
1171
HandleUnMute(std::shared_ptr<UnMuteReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)1172 int32_t WfdSinkScene::HandleUnMute(std::shared_ptr<UnMuteReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
1173 {
1174 SHARING_LOGD("trace.");
1175 (void)reply;
1176 RETURN_INVALID_IF_NULL(msg);
1177 auto sharingAdapter = sharingAdapter_.lock();
1178 RETURN_INVALID_IF_NULL(sharingAdapter);
1179
1180 uint32_t contextId = INVALID_ID;
1181 uint32_t agentId = INVALID_ID;
1182 {
1183 std::unique_lock<std::mutex> lock(mutex_);
1184 auto itemDev = devConnectionMap_.find(msg->deviceId);
1185 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
1186 lock.unlock();
1187 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonymousMAC(msg->deviceId).c_str());
1188 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleUnMute can not find dev");
1189 return -1;
1190 }
1191
1192 contextId = itemDev->second->contextId;
1193 agentId = itemDev->second->agentId;
1194 }
1195
1196 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1197 return -1;
1198 }
1199
1200 return sharingAdapter->Resume(contextId, agentId, MEDIA_TYPE_AUDIO);
1201 }
1202
HandleClose(std::shared_ptr<WfdCloseReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)1203 int32_t WfdSinkScene::HandleClose(std::shared_ptr<WfdCloseReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
1204 {
1205 SHARING_LOGD("trace.");
1206 (void)reply;
1207 RETURN_INVALID_IF_NULL(msg);
1208 auto sharingAdapter = sharingAdapter_.lock();
1209 RETURN_INVALID_IF_NULL(sharingAdapter);
1210
1211 uint32_t contextId = INVALID_ID;
1212 uint32_t agentId = INVALID_ID;
1213
1214 WfdSinkHiSysEvent::GetInstance().ChangeHisysEventScene(SinkBizScene::DISCONNECT_MIRRORING);
1215 WfdSinkHiSysEvent::GetInstance().StartReport(__func__, "", SinkStage::RECEIVE_DISCONNECT_EVENT,
1216 SinkStageRes::SUCCESS);
1217
1218 ConnectionInfo connectionInfo;
1219 {
1220 std::unique_lock<std::mutex> lock(mutex_);
1221 auto itemDev = devConnectionMap_.find(msg->deviceId);
1222 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
1223 lock.unlock();
1224 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonymousMAC(msg->deviceId).c_str());
1225 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleClose can not find dev");
1226 return -1;
1227 }
1228
1229 connectionInfo.ip = itemDev->second->ip;
1230 connectionInfo.mac = itemDev->second->mac;
1231 connectionInfo.state = ConnectionState::DISCONNECTED;
1232 connectionInfo.surfaceId = itemDev->second->surfaceId;
1233 connectionInfo.deviceName = itemDev->second->deviceName;
1234 connectionInfo.primaryDeviceType = itemDev->second->primaryDeviceType;
1235 connectionInfo.secondaryDeviceType = itemDev->second->secondaryDeviceType;
1236
1237 contextId = itemDev->second->contextId;
1238 agentId = itemDev->second->agentId;
1239
1240 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1241 if ((itemSurface->second != nullptr) && (msg->deviceId == itemSurface->second->deviceId)) {
1242 itemSurface->second->deleting = true;
1243 }
1244 itemSurface++;
1245 }
1246
1247 P2pRemoveClient(connectionInfo);
1248
1249 devConnectionMap_.erase(msg->deviceId);
1250 }
1251
1252 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1253 return -1;
1254 }
1255
1256 OnConnectionChanged(connectionInfo);
1257 auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
1258 sessionMsg->type = EVENT_SESSION_TEARDOWN;
1259 sessionMsg->toMgr = MODULE_CONTEXT;
1260 sessionMsg->dstId = contextId;
1261 sessionMsg->agentId = agentId;
1262
1263 SharingEvent event;
1264 event.eventMsg = std::move(sessionMsg);
1265 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
1266
1267 return sharingAdapter->DestroyAgent(contextId, agentId);
1268 }
1269
HandleGetConfig(std::shared_ptr<GetSinkConfigReq> & msg,std::shared_ptr<GetSinkConfigRsp> & reply)1270 int32_t WfdSinkScene::HandleGetConfig(std::shared_ptr<GetSinkConfigReq> &msg, std::shared_ptr<GetSinkConfigRsp> &reply)
1271 {
1272 SHARING_LOGD("trace.");
1273 (void)msg;
1274 RETURN_INVALID_IF_NULL(reply);
1275 reply->accessDevMaximum = static_cast<uint32_t>(accessDevMaximum_);
1276 reply->foregroundMaximum = static_cast<uint32_t>(foregroundMaximum_);
1277 reply->surfaceMaximum = static_cast<uint32_t>(surfaceMaximum_);
1278
1279 return 0;
1280 }
1281
HandleGetBoundDevices(std::shared_ptr<WfdGetBoundDevicesReq> & msg,std::shared_ptr<WfdGetBoundDevicesRsp> & reply)1282 int32_t WfdSinkScene::HandleGetBoundDevices(std::shared_ptr<WfdGetBoundDevicesReq> &msg,
1283 std::shared_ptr<WfdGetBoundDevicesRsp> &reply)
1284 {
1285 SHARING_LOGI("%{public}s.", __FUNCTION__);
1286 (void)msg;
1287 (void)reply;
1288 reply->trustDevices = wfdTrustListManager_.GetAllBoundDevices();
1289 return 0;
1290 }
1291
HandleDeleteBoundDevice(std::shared_ptr<WfdDeleteBoundDeviceReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)1292 int32_t WfdSinkScene::HandleDeleteBoundDevice(std::shared_ptr<WfdDeleteBoundDeviceReq> &msg,
1293 std::shared_ptr<WfdCommonRsp> &reply)
1294 {
1295 SHARING_LOGI("%{public}s.", __FUNCTION__);
1296 (void)reply;
1297 RETURN_INVALID_IF_NULL(msg);
1298 reply->ret = wfdTrustListManager_.DeleteBoundDeviceGroup(msg->deviceAddress);
1299 return 0;
1300 }
1301
RegisterWfdAbilityListener()1302 void WfdSinkScene::RegisterWfdAbilityListener()
1303 {
1304 SHARING_LOGI("%{public}s.", __FUNCTION__);
1305 std::unique_lock<std::mutex> lock(mutex_);
1306 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1307 if (samgrProxy == nullptr) {
1308 SHARING_LOGE("get system ability manager fail");
1309 return;
1310 }
1311 sysAbilityListener_ = new (std::nothrow) WfdSystemAbilityListener(shared_from_this());
1312 if (sysAbilityListener_ == nullptr) {
1313 SHARING_LOGE("sysAbilityListener create failed.");
1314 return;
1315 }
1316 int32_t ret = samgrProxy->SubscribeSystemAbility(WIFI_DEVICE_ABILITY_ID, sysAbilityListener_);
1317 SHARING_LOGI("result is %{public}d.", ret);
1318 }
1319
UnRegisterWfdAbilityListener()1320 void WfdSinkScene::UnRegisterWfdAbilityListener()
1321 {
1322 SHARING_LOGI("%{public}s.", __FUNCTION__);
1323 std::unique_lock<std::mutex> lock(mutex_);
1324 if (sysAbilityListener_ == nullptr) {
1325 SHARING_LOGE("listener is null");
1326 return;
1327 }
1328 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1329 if (samgrProxy == nullptr) {
1330 SHARING_LOGE("get system ability manager fail");
1331 return;
1332 }
1333 int32_t ret = samgrProxy->UnSubscribeSystemAbility(WIFI_DEVICE_ABILITY_ID, sysAbilityListener_);
1334 SHARING_LOGI("result is %{public}d.", ret);
1335 sysAbilityListener_ = nullptr;
1336 }
1337
WfdP2pStart()1338 void WfdSinkScene::WfdP2pStart()
1339 {
1340 SHARING_LOGI("trace.");
1341 if (p2pInstance_) {
1342 Wifi::WifiP2pWfdInfo wfdInfo;
1343 wfdInfo.SetWfdEnabled(true);
1344 wfdInfo.SetDeviceInfo(0x11);
1345 wfdInfo.SetCtrlPort(ctrlPort_);
1346 wfdInfo.SetMaxThroughput(0x00c8);
1347
1348 p2pInstance_->SetP2pWfdInfo(wfdInfo);
1349 p2pInstance_->StartP2pListen(P2P_LISTEN_PERIOD, P2P_LISTEN_INTERVAL);
1350 }
1351 }
1352
WfdP2pStop()1353 void WfdSinkScene::WfdP2pStop()
1354 {
1355 SHARING_LOGI("trace.");
1356 std::unique_lock<std::mutex> lock(mutex_);
1357 auto sharingAdapter = sharingAdapter_.lock();
1358 if (sharingAdapter != nullptr) {
1359 for (auto item : devConnectionMap_) {
1360 uint32_t contextId = item.second->contextId;
1361 uint32_t agentId = item.second->agentId;
1362
1363 if ((contextId != INVALID_ID) && (agentId != INVALID_ID)) {
1364 auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
1365 sessionMsg->type = EVENT_SESSION_TEARDOWN;
1366 sessionMsg->toMgr = MODULE_CONTEXT;
1367 sessionMsg->dstId = contextId;
1368 sessionMsg->agentId = agentId;
1369
1370 SharingEvent event;
1371 event.eventMsg = std::move(sessionMsg);
1372 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
1373
1374 P2pRemoveClient(*(item.second));
1375
1376 sharingAdapter->DestroyAgent(contextId, agentId);
1377 }
1378 }
1379 }
1380
1381 if (p2pInstance_) {
1382 p2pInstance_->StopP2pListen();
1383 }
1384
1385 devSurfaceItemMap_.clear();
1386 devConnectionMap_.clear();
1387 }
1388
FillAndReportDeviceInfo(const ConnectionInfo & connectionInfo)1389 void WfdSinkScene::FillAndReportDeviceInfo(const ConnectionInfo &connectionInfo)
1390 {
1391 Wifi::WifiP2pGroupInfo group;
1392 p2pInstance_->GetCurrentGroup(group);
1393 int32_t netWorkId = group.GetNetworkId();
1394 Wifi::WifiP2pDevice deviceInfo;
1395 p2pInstance_->QueryP2pLocalDevice(deviceInfo);
1396
1397 WfdSinkHiSysEvent::SinkHisyseventDevInfo devInfo;
1398 {
1399 std::unique_lock<std::mutex> lock(localIpMutex_);
1400 devInfo.localIp = localIp_.c_str();
1401 }
1402 devInfo.localWifiMac = deviceInfo.GetDeviceAddress();
1403 devInfo.localDevName = deviceInfo.GetDeviceName();
1404 devInfo.localNetId = std::to_string(netWorkId);
1405 devInfo.peerDevName = connectionInfo.deviceName.c_str();
1406 devInfo.peerIp = connectionInfo.ip.c_str();
1407 devInfo.peerNetId = std::to_string(netWorkId);
1408 devInfo.peerWifiMac = connectionInfo.mac.c_str();
1409
1410 WfdSinkHiSysEvent::GetInstance().SetHiSysEventDevInfo(devInfo);
1411 }
1412
OnP2pPeerConnected(ConnectionInfo & connectionInfo)1413 void WfdSinkScene::OnP2pPeerConnected(ConnectionInfo &connectionInfo)
1414 {
1415 SHARING_LOGD("trace.");
1416 if (!isSinkRunning_) {
1417 SHARING_LOGW("sink service is not running.");
1418 return;
1419 }
1420
1421 auto sharingAdapter = sharingAdapter_.lock();
1422 RETURN_IF_NULL(sharingAdapter);
1423
1424 if (devConnectionMap_.size() >= (uint32_t)accessDevMaximum_) {
1425 SHARING_LOGE("too more device.");
1426 P2pRemoveClient(connectionInfo);
1427
1428 auto ipcAdapter = ipcAdapter_.lock();
1429 RETURN_IF_NULL(ipcAdapter);
1430
1431 auto msg = std::make_shared<WfdErrorMsg>();
1432 msg->message = "Maximum number of devices reached";
1433 msg->errorCode = ERR_RECEIVING_LIMIT;
1434
1435 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1436 ipcAdapter->SendRequest(msg, reply);
1437
1438 return;
1439 }
1440
1441 {
1442 std::unique_lock<std::mutex> lock(mutex_);
1443 if (devConnectionMap_.count(connectionInfo.mac)) {
1444 SHARING_LOGW("devcie is alerady connected, mac: %{private}s.", GetAnonymousMAC(connectionInfo.mac).c_str());
1445 return;
1446 }
1447
1448 uint32_t contextId = INVALID_ID;
1449 uint32_t agentId = INVALID_ID;
1450
1451 sharingAdapter->CreateAgent(contextId, agentId, AgentType::SINK_AGENT, "WfdSinkSession");
1452 if (contextId == INVALID_ID || agentId == INVALID_ID) {
1453 lock.unlock();
1454 SHARING_LOGE("connected, create sink agent failed, devMac: %{private}s.",
1455 GetAnonymousMAC(connectionInfo.mac).c_str());
1456 return;
1457 } else {
1458 SHARING_LOGI("connected, create sink agent, contextId: %{public}u, "
1459 "agentId: %{public}u, devMac: %{private}s, devIp: %{private}s.", contextId, agentId,
1460 GetAnonymousMAC(connectionInfo.mac).c_str(), GetAnonymousIp(connectionInfo.ip).c_str());
1461 FillAndReportDeviceInfo(connectionInfo);
1462 std::chrono::system_clock::time_point startTime = std::chrono::system_clock::now();
1463 WfdSinkHiSysEvent::GetInstance().GetStartTime(startTime);
1464 WfdSinkHiSysEvent::GetInstance().ChangeHisysEventScene(SinkBizScene::ESTABLISH_MIRRORING);
1465 WfdSinkHiSysEvent::GetInstance().StartReport(__func__, "wpa_supplicant", SinkStage::P2P_CONNECT_SUCCESS,
1466 SinkStageRes::SUCCESS);
1467 }
1468
1469 connectionInfo.contextId = contextId;
1470 connectionInfo.agentId = agentId;
1471 connectionInfo.videoCodecId = videoCodecId_;
1472 connectionInfo.videoFormatId = videoFormatId_;
1473 connectionInfo.audioCodecId = audioCodecId_;
1474 connectionInfo.audioFormatId = audioFormatId_;
1475
1476 std::shared_ptr<ConnectionInfo> connectionInfoPtr = std::make_shared<ConnectionInfo>(connectionInfo);
1477 RETURN_IF_NULL(connectionInfoPtr);
1478 devConnectionMap_.emplace(connectionInfo.mac, connectionInfoPtr);
1479 SHARING_LOGI("connected, devMac: %{private}s, devIp: %{private}s.", GetAnonymousMAC(connectionInfo.mac).c_str(),
1480 GetAnonymousIp(connectionInfo.ip).c_str());
1481 }
1482 SetWifiScene(1);
1483 OnConnectionChanged(connectionInfo);
1484 }
1485
OnP2pPeerDisconnected(ConnectionInfo & connectionInfo)1486 void WfdSinkScene::OnP2pPeerDisconnected(ConnectionInfo &connectionInfo)
1487 {
1488 SHARING_LOGD("trace.");
1489 auto sharingAdapter = sharingAdapter_.lock();
1490 RETURN_IF_NULL(sharingAdapter);
1491
1492 uint32_t contextId = INVALID_ID;
1493 uint32_t agentId = INVALID_ID;
1494 {
1495 std::unique_lock<std::mutex> lock(mutex_);
1496 auto itemDev = devConnectionMap_.find(connectionInfo.mac);
1497 if (itemDev == devConnectionMap_.end()) {
1498 lock.unlock();
1499 SHARING_LOGW("can not find dev, mac: %{private}s.", GetAnonymousMAC(connectionInfo.mac).c_str());
1500 return;
1501 }
1502 contextId = itemDev->second->contextId;
1503 agentId = itemDev->second->agentId;
1504 connectionInfo.surfaceId = itemDev->second->surfaceId;
1505
1506 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1507 if (connectionInfo.mac == itemSurface->second->deviceId) {
1508 itemSurface->second->deleting = true;
1509 }
1510 itemSurface++;
1511 }
1512
1513 P2pRemoveClient(connectionInfo);
1514
1515 devConnectionMap_.erase(connectionInfo.mac);
1516 SHARING_LOGI("disconnected, contextId: %{public}u, agentId: %{public}u, devMac: %{private}s.", contextId,
1517 agentId, GetAnonymousMAC(connectionInfo.mac).c_str());
1518 }
1519
1520 OnConnectionChanged(connectionInfo);
1521
1522 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1523 return;
1524 }
1525
1526 auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
1527 sessionMsg->type = EVENT_SESSION_TEARDOWN;
1528 sessionMsg->toMgr = MODULE_CONTEXT;
1529 sessionMsg->dstId = contextId;
1530 sessionMsg->agentId = agentId;
1531
1532 SharingEvent event;
1533 event.eventMsg = std::move(sessionMsg);
1534
1535 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
1536 sharingAdapter->DestroyAgent(contextId, agentId);
1537 }
1538
OnP2pPeerDisconnected(const std::string & mac)1539 void WfdSinkScene::OnP2pPeerDisconnected(const std::string &mac)
1540 {
1541 SHARING_LOGD("trace.");
1542 uint32_t contextId = INVALID_ID;
1543 uint32_t agentId = INVALID_ID;
1544 std::shared_ptr<ConnectionInfo> connectionInfo = nullptr;
1545 {
1546 std::unique_lock<std::mutex> lock(mutex_);
1547 auto itemDev = devConnectionMap_.find(mac);
1548 if (itemDev == devConnectionMap_.end()) {
1549 lock.unlock();
1550 SHARING_LOGW("can not find dev, mac: %{private}s.", GetAnonymousMAC(mac).c_str());
1551 return;
1552 }
1553 contextId = itemDev->second->contextId;
1554 agentId = itemDev->second->agentId;
1555 connectionInfo = itemDev->second;
1556
1557 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1558 if (mac == itemSurface->second->deviceId) {
1559 itemSurface->second->deleting = true;
1560 }
1561 itemSurface++;
1562 }
1563
1564 SHARING_LOGI("disconnected, contextId: %{public}u, agentId: %{public}u, devMac: %{private}s.", contextId,
1565 agentId, GetAnonymousMAC(mac).c_str());
1566 P2pRemoveClient(*connectionInfo);
1567
1568 devConnectionMap_.erase(mac);
1569 }
1570
1571 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1572 return;
1573 }
1574
1575 auto sharingAdapter = sharingAdapter_.lock();
1576 if (sharingAdapter != nullptr) {
1577 sharingAdapter->DestroyAgent(contextId, agentId);
1578 }
1579
1580 if (connectionInfo != nullptr) {
1581 connectionInfo->state = ConnectionState::DISCONNECTED;
1582 OnConnectionChanged(*connectionInfo);
1583 }
1584 }
1585
ErrorCodeFiltering(int32_t & code)1586 void WfdSinkScene::ErrorCodeFiltering(int32_t &code)
1587 {
1588 SHARING_LOGD("the error code is %{public}d.", code);
1589 switch (ABSTRACT_ERR_BASE(code)) {
1590 case SharingErrorCode::ERR_CONTEXT_AGENT_BASE: // fall-through
1591 case SharingErrorCode::ERR_SESSION_BASE:
1592 code = SharingErrorCode::ERR_GENERAL_ERROR;
1593 SHARING_LOGD("the error change to %{public}d.", code);
1594 break;
1595 case SharingErrorCode::ERR_PROSUMER_BASE: {
1596 switch (code) {
1597 case ERR_PROSUMER_START:
1598 code = SharingErrorCode::ERR_CONNECTION_FAILURE;
1599 break;
1600 case ERR_PROSUMER_TIMEOUT:
1601 code = SharingErrorCode::ERR_CONNECTION_TIMEOUT;
1602 break;
1603 case ERR_PROSUMER_DESTROY:
1604 code = SharingErrorCode::ERR_STATE_EXCEPTION;
1605 break;
1606 default:
1607 code = SharingErrorCode::ERR_GENERAL_ERROR;
1608 break;
1609 }
1610 break;
1611 }
1612 default:
1613 SHARING_LOGI("none process case.");
1614 break;
1615 }
1616 }
1617
OnInnerError(uint32_t contextId,uint32_t agentId,SharingErrorCode errorCode,std::string message)1618 void WfdSinkScene::OnInnerError(uint32_t contextId, uint32_t agentId, SharingErrorCode errorCode, std::string message)
1619 {
1620 SHARING_LOGD("trace.");
1621 auto ipcAdapter = ipcAdapter_.lock();
1622 RETURN_IF_NULL(ipcAdapter);
1623
1624 auto msg = std::make_shared<WfdErrorMsg>();
1625 msg->contextId = contextId;
1626 msg->agentId = agentId;
1627 msg->errorCode = errorCode;
1628
1629 for (auto &item : devConnectionMap_) {
1630 if ((contextId == item.second->contextId) && (agentId == item.second->agentId)) {
1631 msg->mac = item.second->mac;
1632 break;
1633 }
1634 }
1635
1636 if (errorCode == SharingErrorCode::ERR_PROSUMER_TIMEOUT) {
1637 msg->message =
1638 "contextId: " + std::to_string(contextId) + ", agentId: " + std::to_string(agentId) + ", producer timeout";
1639 } else {
1640 msg->message = std::move(message);
1641 }
1642
1643 ErrorCodeFiltering(msg->errorCode);
1644 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1645
1646 SHARING_LOGW("receive errorCode: %{public}d.", errorCode);
1647 ipcAdapter->SendRequest(msg, reply);
1648 }
1649
OnInnerError(std::string deviceId,SharingErrorCode errorCode,std::string message)1650 void WfdSinkScene::OnInnerError(std::string deviceId, SharingErrorCode errorCode, std::string message)
1651 {
1652 SHARING_LOGD("trace.");
1653 auto ipcAdapter = ipcAdapter_.lock();
1654 RETURN_IF_NULL(ipcAdapter);
1655
1656 auto msg = std::make_shared<WfdErrorMsg>();
1657 msg->message = message;
1658 msg->mac = deviceId;
1659 msg->errorCode = errorCode;
1660
1661 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1662
1663 SHARING_LOGW("receive errorCode: %{public}d.", errorCode);
1664 ipcAdapter->SendRequest(msg, reply);
1665 }
1666
OnInnerDestroy(uint32_t contextId,uint32_t agentId,AgentType agentType)1667 void WfdSinkScene::OnInnerDestroy(uint32_t contextId, uint32_t agentId, AgentType agentType)
1668 {
1669 SHARING_LOGI("HandleInnerDestroy, contextId: %{public}u, agentId: %{public}u, agentType: %{public}s.", contextId,
1670 agentId, std::string(magic_enum::enum_name(agentType)).c_str());
1671
1672 std::unique_lock<std::mutex> lock(mutex_);
1673 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1674 if ((itemSurface->second != nullptr) && (contextId == itemSurface->second->contextId) &&
1675 (agentId == itemSurface->second->agentId)) {
1676 itemSurface = devSurfaceItemMap_.erase(itemSurface);
1677 } else {
1678 itemSurface++;
1679 }
1680 }
1681
1682 for (auto &item : devConnectionMap_) {
1683 if ((item.second != nullptr) && (contextId == item.second->contextId) && (agentId == item.second->agentId)) {
1684 ConnectionInfo connectionInfo;
1685 connectionInfo.ip = item.second->ip;
1686 connectionInfo.mac = item.second->mac;
1687 connectionInfo.deviceName = item.second->deviceName;
1688 connectionInfo.primaryDeviceType = item.second->primaryDeviceType;
1689 connectionInfo.secondaryDeviceType = item.second->secondaryDeviceType;
1690 connectionInfo.ctrlPort = item.second->ctrlPort;
1691 connectionInfo.state = ConnectionState::DISCONNECTED;
1692
1693 SHARING_LOGI(
1694 "disconnected, contextId: %{public}u, agentId: %{public}u, devMac: %{private}s, devIp: %{private}s.",
1695 contextId, agentId, GetAnonymousMAC(connectionInfo.mac).c_str(),
1696 GetAnonymousIp(connectionInfo.ip).c_str());
1697 OnConnectionChanged(connectionInfo);
1698
1699 P2pRemoveClient(connectionInfo);
1700
1701 devConnectionMap_.erase(item.second->mac);
1702 break;
1703 }
1704 }
1705 }
1706
OnInnerEvent(SharingEvent & event)1707 void WfdSinkScene::OnInnerEvent(SharingEvent &event)
1708 {
1709 SHARING_LOGD("trace.");
1710 RETURN_IF_NULL(event.eventMsg);
1711
1712 SHARING_LOGI("eventType: %{public}s.", std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
1713 switch (event.eventMsg->type) {
1714 case EventType::EVENT_WFD_NOTIFY_RTSP_PLAYED: {
1715 auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
1716 if (msg) {
1717 std::unique_lock<std::mutex> lock(mutex_);
1718 auto itConnection = devConnectionMap_.find(msg->mac);
1719 if (itConnection == devConnectionMap_.end()) {
1720 SHARING_LOGD("can't find dev %{private}s.", GetAnonymousMAC(msg->mac).c_str());
1721 break;
1722 }
1723
1724 itConnection->second->state = ConnectionState::PLAYING;
1725 OnConnectionChanged(*itConnection->second);
1726 }
1727 break;
1728 }
1729 case EventType::EVENT_WFD_NOTIFY_RTSP_TEARDOWN: {
1730 auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
1731 if (msg) {
1732 OnP2pPeerDisconnected(msg->mac);
1733 }
1734 break;
1735 }
1736 case EventType::EVENT_INTERACTION_ACCELERATION_DONE: {
1737 auto msg = ConvertEventMsg<InteractionEventMsg>(event);
1738 SHARING_LOGD("On acceleration done, contextId: %{public}d agentId: %{public}d.", msg->contextId,
1739 msg->agentId);
1740 std::unique_lock<std::mutex> lock(mutex_);
1741 for (auto connectInfoPair : devConnectionMap_) {
1742 if (connectInfoPair.second != nullptr && connectInfoPair.second->contextId == msg->contextId &&
1743 connectInfoPair.second->agentId == msg->agentId) {
1744 SHARING_LOGD("On acceleration done, device found.");
1745 auto connectInfo = connectInfoPair.second;
1746 connectInfo->surfaceId = msg->surfaceId;
1747
1748 OnDecoderAccelerationDone(*connectInfo);
1749 break;
1750 }
1751 SHARING_LOGW("On acceleration done, device not found.");
1752 }
1753 break;
1754 }
1755 case EventType::EVENT_INTERACTION_STATE_REMOVE_SURFACE: {
1756 auto msg = ConvertEventMsg<InteractionEventMsg>(event);
1757 SHARING_LOGD("On state remove surface, agentId: %{public}d.", msg->agentId);
1758 std::unique_lock<std::mutex> lock(mutex_);
1759 devSurfaceItemMap_.erase(msg->surfaceId);
1760 break;
1761 }
1762 case EVENT_INTERACTION_DECODER_DIED: {
1763 auto msg = ConvertEventMsg<InteractionEventMsg>(event);
1764 auto surfaceItem = devSurfaceItemMap_.find(msg->surfaceId);
1765 if (surfaceItem != devSurfaceItemMap_.end() && surfaceItem->second != nullptr) {
1766 auto itConnection = devConnectionMap_.find(surfaceItem->second->deviceId);
1767 OnDecoderDied(*itConnection->second);
1768 }
1769 break;
1770 }
1771 default:
1772 SHARING_LOGI("none process case.");
1773 break;
1774 }
1775 }
1776
OnConnectionChanged(ConnectionInfo & connectionInfo)1777 void WfdSinkScene::OnConnectionChanged(ConnectionInfo &connectionInfo)
1778 {
1779 SHARING_LOGD("trace.");
1780 auto ipcAdapter = ipcAdapter_.lock();
1781 RETURN_IF_NULL(ipcAdapter);
1782
1783 auto msg = std::make_shared<WfdConnectionChangedMsg>();
1784 msg->ip = connectionInfo.ip;
1785 msg->mac = connectionInfo.mac;
1786 msg->state = connectionInfo.state;
1787 msg->surfaceId = connectionInfo.surfaceId;
1788 msg->deviceName = connectionInfo.deviceName;
1789 msg->primaryDeviceType = connectionInfo.primaryDeviceType;
1790 msg->secondaryDeviceType = connectionInfo.secondaryDeviceType;
1791
1792 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1793 ipcAdapter->SendRequest(msg, reply);
1794 }
1795
P2pRemoveClient(ConnectionInfo & connectionInfo)1796 void WfdSinkScene::P2pRemoveClient(ConnectionInfo &connectionInfo)
1797 {
1798 SHARING_LOGI("p2p remove client: %{private}s.", GetAnonymousMAC(connectionInfo.mac).c_str());
1799 {
1800 std::unique_lock<std::mutex> lock(currentConnectDevMutex_);
1801 currentConnectDev_.mac = "";
1802 }
1803 SetWifiScene(0);
1804 if (!p2pInstance_) {
1805 SHARING_LOGE("p2p instance is null");
1806 return;
1807 }
1808
1809 OHOS::Wifi::GcInfo info;
1810 info.mac = connectionInfo.mac;
1811 info.ip = connectionInfo.ip;
1812 info.host = connectionInfo.deviceName;
1813
1814 p2pInstance_->RemoveGroupClient(info);
1815 }
1816
OnDecoderAccelerationDone(ConnectionInfo & connectionInfo)1817 void WfdSinkScene::OnDecoderAccelerationDone(ConnectionInfo &connectionInfo)
1818 {
1819 SHARING_LOGD("trace.");
1820 auto ipcAdapter = ipcAdapter_.lock();
1821 RETURN_IF_NULL(ipcAdapter);
1822
1823 auto msg = std::make_shared<WfdDecoderAccelerationDoneMsg>();
1824 msg->surfaceId = connectionInfo.surfaceId;
1825
1826 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1827 ipcAdapter->SendRequest(msg, reply);
1828 SHARING_LOGD("device ip: %{private}s, mac: %{private}s, state: %{public}s.",
1829 GetAnonymousIp(connectionInfo.ip).c_str(), GetAnonymousMAC(connectionInfo.mac).c_str(),
1830 std::string(magic_enum::enum_name(connectionInfo.state)).c_str());
1831 }
1832
OnDecoderDied(ConnectionInfo & connectionInfo)1833 void WfdSinkScene::OnDecoderDied(ConnectionInfo &connectionInfo)
1834 {
1835 SHARING_LOGD("trace.");
1836 auto ipcAdapter = ipcAdapter_.lock();
1837 RETURN_IF_NULL(ipcAdapter);
1838
1839 auto msg = std::make_shared<WfdSurfaceFailureMsg>();
1840 msg->surfaceId = connectionInfo.surfaceId;
1841 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1842 ipcAdapter->SendRequest(msg, reply);
1843
1844 SHARING_LOGD("failed at device ip: %{private}s, mac: %{private}s, state: %{public}s.",
1845 GetAnonymousIp(connectionInfo.ip).c_str(), GetAnonymousMAC(connectionInfo.mac).c_str(),
1846 std::string(magic_enum::enum_name(connectionInfo.state)).c_str());
1847 }
1848
OnRemoteDied()1849 void WfdSinkScene::OnRemoteDied()
1850 {
1851 SHARING_LOGD("trace.");
1852 auto sharingAdapter = sharingAdapter_.lock();
1853 if (sharingAdapter) {
1854 sharingAdapter->ReleaseScene(GetId());
1855 }
1856 }
1857
1858 REGISTER_CLASS_REFLECTOR(WfdSinkScene);
1859 } // namespace Sharing
1860 } // namespace OHOS
1861