1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "mouse_location.h" 17 18#include "devicestatus_define.h"s 19#include "dsoftbus_handler.h" 20#include "utility.h" 21 22#undef LOG_TAG 23#define LOG_TAG "MouseLocation" 24 25namespace OHOS { 26namespace Msdp { 27namespace DeviceStatus { 28namespace Cooperate { 29 30MouseLocation::MouseLocation(IContext *context) : context_(context) {} 31 32void MouseLocation::AddListener(const RegisterEventListenerEvent &event) 33{ 34 CALL_INFO_TRACE; 35 std::lock_guard<std::mutex> guard(mutex_); 36 localNetworkId_ = IDSoftbusAdapter::GetLocalNetworkId(); 37 if (event.networkId == localNetworkId_) { 38 FI_HILOGI("Add local mouse location listener"); 39 localListeners_.insert(event.pid); 40 return; 41 } 42 FI_HILOGI("Add remote mouse location listener, networkId:%{public}s", Utility::Anonymize(event.networkId).c_str()); 43 DSoftbusSubscribeMouseLocation softbusEvent { 44 .networkId = localNetworkId_, 45 .remoteNetworkId = event.networkId, 46 }; 47 if (SubscribeMouseLocation(softbusEvent) != RET_OK) { 48 FI_HILOGE("SubscribeMouseLocation failed, networkId:%{public}s", Utility::Anonymize(event.networkId).c_str()); 49 return; 50 } 51 listeners_[event.networkId].insert(event.pid); 52} 53 54void MouseLocation::RemoveListener(const UnregisterEventListenerEvent &event) 55{ 56 CALL_INFO_TRACE; 57 std::lock_guard<std::mutex> guard(mutex_); 58 localNetworkId_ = IDSoftbusAdapter::GetLocalNetworkId(); 59 if (event.networkId == localNetworkId_) { 60 FI_HILOGI("Remove local mouse location listener"); 61 localListeners_.erase(event.pid); 62 return; 63 } 64 DSoftbusUnSubscribeMouseLocation softbusEvent { 65 .networkId = localNetworkId_, 66 .remoteNetworkId = event.networkId, 67 }; 68 if (UnSubscribeMouseLocation(softbusEvent) != RET_OK) { 69 FI_HILOGE("UnSubscribeMouseLocation failed, networkId:%{public}s", Utility::Anonymize(event.networkId).c_str()); 70 } 71 if (listeners_.find(event.networkId) == listeners_.end()) { 72 FI_HILOGE("No listener for networkId:%{public}s", Utility::Anonymize(event.networkId).c_str()); 73 return; 74 } 75 listeners_[event.networkId].erase(event.pid); 76 if (listeners_[event.networkId].empty()) { 77 listeners_.erase(event.networkId); 78 } 79} 80 81void MouseLocation::OnClientDied(const ClientDiedEvent &event) 82{ 83 CALL_INFO_TRACE; 84 std::lock_guard<std::mutex> guard(mutex_); 85 localNetworkId_ = IDSoftbusAdapter::GetLocalNetworkId(); 86 FI_HILOGI("Remove client died listener, pid: %{public}d", event.pid); 87 localListeners_.erase(event.pid); 88 for (auto it = listeners_.begin(); it != listeners_.end();) { 89 it->second.erase(event.pid); 90 if (it->second.empty()) { 91 DSoftbusUnSubscribeMouseLocation softbusEvent { 92 .networkId = localNetworkId_, 93 .remoteNetworkId = it->first, 94 }; 95 UnSubscribeMouseLocation(softbusEvent); 96 it = listeners_.erase(it); 97 } else { 98 ++it; 99 } 100 } 101} 102 103void MouseLocation::OnSoftbusSessionClosed(const DSoftbusSessionClosed ¬ice) 104{ 105 CALL_INFO_TRACE; 106 std::lock_guard<std::mutex> guard(mutex_); 107 FI_HILOGI("Session to %{public}s closed", Utility::Anonymize(notice.networkId).c_str()); 108 if (remoteSubscribers_.find(notice.networkId) != remoteSubscribers_.end()) { 109 remoteSubscribers_.erase(notice.networkId); 110 FI_HILOGI("Remove remote subscribers from %{public}s", Utility::Anonymize(notice.networkId).c_str()); 111 } 112 if (listeners_.find(notice.networkId) != listeners_.end()) { 113 listeners_.erase(notice.networkId); 114 FI_HILOGI("Remove listeners listen to %{public}s", Utility::Anonymize(notice.networkId).c_str()); 115 } 116} 117 118void MouseLocation::OnSubscribeMouseLocation(const DSoftbusSubscribeMouseLocation ¬ice) 119{ 120 CALL_INFO_TRACE; 121 std::lock_guard<std::mutex> guard(mutex_); 122 CHKPV(context_); 123 remoteSubscribers_.insert(notice.networkId); 124 FI_HILOGI("Add subscriber for networkId:%{public}s successfully", Utility::Anonymize(notice.networkId).c_str()); 125 DSoftbusReplySubscribeMouseLocation event = { 126 .networkId = notice.remoteNetworkId, 127 .remoteNetworkId = notice.networkId, 128 .result = true, 129 }; 130 FI_HILOGI("ReplySubscribeMouseLocation from networkId:%{public}s to networkId:%{public}s", 131 Utility::Anonymize(event.networkId).c_str(), Utility::Anonymize(event.remoteNetworkId).c_str()); 132 ReplySubscribeMouseLocation(event); 133} 134 135void MouseLocation::OnUnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation ¬ice) 136{ 137 CALL_INFO_TRACE; 138 std::lock_guard<std::mutex> guard(mutex_); 139 localNetworkId_ = IDSoftbusAdapter::GetLocalNetworkId(); 140 if (remoteSubscribers_.find(notice.networkId) == remoteSubscribers_.end()) { 141 FI_HILOGE("No subscriber for networkId:%{public}s stored in remote subscriber", 142 Utility::Anonymize(notice.networkId).c_str()); 143 return; 144 } 145 remoteSubscribers_.erase(notice.networkId); 146 DSoftbusReplyUnSubscribeMouseLocation event = { 147 .networkId = notice.remoteNetworkId, 148 .remoteNetworkId = notice.networkId, 149 .result = true, 150 }; 151 FI_HILOGI("ReplyUnSubscribeMouseLocation from networkId:%{public}s to networkId:%{public}s", 152 Utility::Anonymize(event.networkId).c_str(), Utility::Anonymize(event.remoteNetworkId).c_str()); 153 ReplyUnSubscribeMouseLocation(event); 154} 155 156void MouseLocation::OnReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation ¬ice) 157{ 158 CALL_INFO_TRACE; 159 std::lock_guard<std::mutex> guard(mutex_); 160 if (notice.result) { 161 FI_HILOGI("SubscribeMouseLocation of networkId:%{public}s successfully, localNetworkId:%{public}s", 162 Utility::Anonymize(notice.networkId).c_str(), Utility::Anonymize(notice.remoteNetworkId).c_str()); 163 } else { 164 FI_HILOGI("SubscribeMouseLocation of networkId:%{public}s failed, localNetworkId:%{public}s", 165 Utility::Anonymize(notice.networkId).c_str(), Utility::Anonymize(notice.remoteNetworkId).c_str()); 166 } 167} 168 169void MouseLocation::OnReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation ¬ice) 170{ 171 CALL_INFO_TRACE; 172 std::lock_guard<std::mutex> guard(mutex_); 173 if (notice.result) { 174 FI_HILOGI("UnSubscribeMouseLocation of networkId:%{public}s successfully, localNetworkId:%{public}s", 175 Utility::Anonymize(notice.networkId).c_str(), Utility::Anonymize(notice.remoteNetworkId).c_str()); 176 } else { 177 FI_HILOGI("UnSubscribeMouseLocation of networkId:%{public}s failed, localNetworkId:%{public}s", 178 Utility::Anonymize(notice.networkId).c_str(), Utility::Anonymize(notice.remoteNetworkId).c_str()); 179 } 180} 181 182void MouseLocation::OnRemoteMouseLocation(const DSoftbusSyncMouseLocation ¬ice) 183{ 184 CALL_DEBUG_ENTER; 185 std::lock_guard<std::mutex> guard(mutex_); 186 if (listeners_.find(notice.networkId) == listeners_.end()) { 187 FI_HILOGE("No listener for networkId:%{public}s stored in listeners", 188 Utility::Anonymize(notice.networkId).c_str()); 189 return; 190 } 191 LocationInfo locationInfo { 192 .displayX = notice.mouseLocation.displayX, 193 .displayY = notice.mouseLocation.displayY, 194 .displayWidth = notice.mouseLocation.displayWidth, 195 .displayHeight = notice.mouseLocation.displayHeight 196 }; 197 for (auto pid : listeners_[notice.networkId]) { 198 ReportMouseLocationToListener(notice.networkId, locationInfo, pid); 199 } 200} 201 202void MouseLocation::ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent) 203{ 204 CALL_DEBUG_ENTER; 205 std::lock_guard<std::mutex> guard(mutex_); 206 CHKPV(pointerEvent); 207 if (auto sourceType = pointerEvent->GetSourceType(); sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) { 208 FI_HILOGD("Unexpected sourceType:%{public}d", static_cast<int32_t>(sourceType)); 209 return; 210 } 211 LocationInfo locationInfo; 212 TransferToLocationInfo(pointerEvent, locationInfo); 213 if (HasLocalListener()) { 214 for (auto pid : localListeners_) { 215 ReportMouseLocationToListener(localNetworkId_, locationInfo, pid); 216 } 217 } 218 if (!HasRemoteSubscriber()) { 219 FI_HILOGD("No remote subscriber"); 220 return; 221 } 222 for (const auto &networkId : remoteSubscribers_) { 223 SyncLocationToRemote(networkId, locationInfo); 224 } 225} 226 227void MouseLocation::SyncLocationToRemote(const std::string &remoteNetworkId, const LocationInfo &locationInfo) 228{ 229 CALL_DEBUG_ENTER; 230 DSoftbusSyncMouseLocation softbusEvent { 231 .networkId = localNetworkId_, 232 .remoteNetworkId = remoteNetworkId, 233 .mouseLocation = { 234 .displayX = locationInfo.displayX, 235 .displayY = locationInfo.displayY, 236 .displayWidth = locationInfo.displayWidth, 237 .displayHeight = locationInfo.displayHeight, 238 }, 239 }; 240 SyncMouseLocation(softbusEvent); 241} 242 243int32_t MouseLocation::ReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation &event) 244{ 245 CALL_INFO_TRACE; 246 NetPacket packet(MessageId::DSOFTBUS_REPLY_SUBSCRIBE_MOUSE_LOCATION); 247 packet << event.networkId << event.remoteNetworkId << event.result; 248 if (packet.ChkRWError()) { 249 FI_HILOGE("Failed to write data packet"); 250 return RET_ERR; 251 } 252 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) { 253 FI_HILOGE("SendPacket failed"); 254 return RET_ERR; 255 } 256 return RET_OK; 257} 258 259int32_t MouseLocation::ReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation &event) 260{ 261 CALL_INFO_TRACE; 262 NetPacket packet(MessageId::DSOFTBUS_REPLY_UNSUBSCRIBE_MOUSE_LOCATION); 263 packet << event.networkId << event.remoteNetworkId << event.result; 264 if (packet.ChkRWError()) { 265 FI_HILOGE("Failed to write data packet"); 266 return RET_ERR; 267 } 268 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) { 269 FI_HILOGE("SendPacket failed"); 270 return RET_ERR; 271 } 272 return RET_OK; 273} 274 275int32_t MouseLocation::SubscribeMouseLocation(const DSoftbusSubscribeMouseLocation &event) 276{ 277 CALL_INFO_TRACE; 278 NetPacket packet(MessageId::DSOFTBUS_SUBSCRIBE_MOUSE_LOCATION); 279 packet << event.networkId << event.remoteNetworkId; 280 if (packet.ChkRWError()) { 281 FI_HILOGE("Failed to write data packet"); 282 return RET_ERR; 283 } 284 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) { 285 FI_HILOGE("SendPacket failed"); 286 return RET_ERR; 287 } 288 return RET_OK; 289} 290 291int32_t MouseLocation::UnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation &event) 292{ 293 CALL_INFO_TRACE; 294 NetPacket packet(MessageId::DSOFTBUS_UNSUBSCRIBE_MOUSE_LOCATION); 295 packet << event.networkId << event.remoteNetworkId; 296 if (packet.ChkRWError()) { 297 FI_HILOGE("Failed to write data packet"); 298 return RET_ERR; 299 } 300 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) { 301 FI_HILOGE("SendPacket failed"); 302 return RET_ERR; 303 } 304 return RET_OK; 305} 306 307int32_t MouseLocation::SyncMouseLocation(const DSoftbusSyncMouseLocation &event) 308{ 309 CALL_DEBUG_ENTER; 310 NetPacket packet(MessageId::DSOFTBUS_MOUSE_LOCATION); 311 packet << event.networkId << event.remoteNetworkId << event.mouseLocation.displayX << 312 event.mouseLocation.displayY << event.mouseLocation.displayWidth << event.mouseLocation.displayHeight; 313 if (packet.ChkRWError()) { 314 FI_HILOGE("Failed to write data packet"); 315 return RET_ERR; 316 } 317 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) { 318 FI_HILOGE("SendPacket failed"); 319 return RET_ERR; 320 } 321 return RET_OK; 322} 323 324void MouseLocation::ReportMouseLocationToListener(const std::string &networkId, const LocationInfo &locationInfo, 325 int32_t pid) 326{ 327 CALL_DEBUG_ENTER; 328 CHKPV(context_); 329 auto session = context_->GetSocketSessionManager().FindSessionByPid(pid); 330 CHKPV(session); 331 NetPacket pkt(MessageId::MOUSE_LOCATION_ADD_LISTENER); 332 pkt << networkId << locationInfo.displayX << locationInfo.displayY << 333 locationInfo.displayWidth << locationInfo.displayHeight; 334 if (pkt.ChkRWError()) { 335 FI_HILOGE("Packet write data failed"); 336 return; 337 } 338 if (!session->SendMsg(pkt)) { 339 FI_HILOGE("Sending failed"); 340 return; 341 } 342} 343 344void MouseLocation::TransferToLocationInfo(std::shared_ptr<MMI::PointerEvent> pointerEvent, LocationInfo &locationInfo) 345{ 346 CALL_DEBUG_ENTER; 347 CHKPV(pointerEvent); 348 MMI::PointerEvent::PointerItem pointerItem; 349 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) { 350 FI_HILOGE("Corrupted pointer event"); 351 return; 352 } 353 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay(); 354 CHKPV(display); 355 locationInfo = { 356 .displayX = pointerItem.GetDisplayX(), 357 .displayY = pointerItem.GetDisplayY(), 358 .displayWidth = display->GetWidth(), 359 .displayHeight = display->GetHeight(), 360 }; 361} 362 363bool MouseLocation::HasRemoteSubscriber() 364{ 365 CALL_DEBUG_ENTER; 366 return !remoteSubscribers_.empty(); 367} 368 369bool MouseLocation::HasLocalListener() 370{ 371 CALL_DEBUG_ENTER; 372 return !localListeners_.empty(); 373} 374 375int32_t MouseLocation::SendPacket(const std::string &remoteNetworkId, NetPacket &packet) 376{ 377 CALL_DEBUG_ENTER; 378 CHKPR(context_, RET_ERR); 379 if (!context_->GetDSoftbus().HasSessionExisted(remoteNetworkId)) { 380 FI_HILOGE("No session connected to %{public}s", Utility::Anonymize(remoteNetworkId).c_str()); 381 return RET_ERR; 382 } 383 if (context_->GetDSoftbus().SendPacket(remoteNetworkId, packet) != RET_OK) { 384 FI_HILOGE("SendPacket failed to %{public}s", Utility::Anonymize(remoteNetworkId).c_str()); 385 return RET_ERR; 386 } 387 return RET_OK; 388} 389 390} // namespace Cooperate 391} // namespace DeviceStatus 392} // namespace Msdp 393} // namespace OHOS 394