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"
19 #include "dsoftbus_handler.h"
20 #include "utility.h"
21
22 #undef LOG_TAG
23 #define LOG_TAG "MouseLocation"
24
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28 namespace Cooperate {
29
MouseLocation(IContext * context)30 MouseLocation::MouseLocation(IContext *context) : context_(context) {}
31
AddListener(const RegisterEventListenerEvent & event)32 void 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 SubscribeMouseLocation(softbusEvent);
48 listeners_[event.networkId].insert(event.pid);
49 }
50
RemoveListener(const UnregisterEventListenerEvent & event)51 void MouseLocation::RemoveListener(const UnregisterEventListenerEvent &event)
52 {
53 CALL_INFO_TRACE;
54 std::lock_guard<std::mutex> guard(mutex_);
55 localNetworkId_ = IDSoftbusAdapter::GetLocalNetworkId();
56 if (event.networkId == localNetworkId_) {
57 FI_HILOGI("Remove local mouse location listener");
58 localListeners_.erase(event.pid);
59 return;
60 }
61 DSoftbusUnSubscribeMouseLocation softbusEvent {
62 .networkId = localNetworkId_,
63 .remoteNetworkId = event.networkId,
64 };
65 UnSubscribeMouseLocation(softbusEvent);
66 if (listeners_.find(event.networkId) != listeners_.end()) {
67 FI_HILOGE("No listener for networkId:%{public}s", Utility::Anonymize(event.networkId).c_str());
68 return;
69 }
70 listeners_[event.networkId].erase(event.pid);
71 if (listeners_[event.networkId].empty()) {
72 listeners_.erase(event.networkId);
73 }
74 }
75
OnClientDied(const ClientDiedEvent & event)76 void MouseLocation::OnClientDied(const ClientDiedEvent &event)
77 {
78 CALL_INFO_TRACE;
79 std::lock_guard<std::mutex> guard(mutex_);
80 localNetworkId_ = IDSoftbusAdapter::GetLocalNetworkId();
81 FI_HILOGI("Remove client died listener, pid: %{public}d", event.pid);
82 localListeners_.erase(event.pid);
83 for (auto it = listeners_.begin(); it != listeners_.end();) {
84 it->second.erase(event.pid);
85 if (it->second.empty()) {
86 DSoftbusUnSubscribeMouseLocation softbusEvent {
87 .networkId = localNetworkId_,
88 .remoteNetworkId = it->first,
89 };
90 UnSubscribeMouseLocation(softbusEvent);
91 it = listeners_.erase(it);
92 } else {
93 ++it;
94 }
95 }
96 }
97
OnSubscribeMouseLocation(const DSoftbusSubscribeMouseLocation & notice)98 void MouseLocation::OnSubscribeMouseLocation(const DSoftbusSubscribeMouseLocation ¬ice)
99 {
100 CALL_INFO_TRACE;
101 std::lock_guard<std::mutex> guard(mutex_);
102 CHKPV(context_);
103 remoteSubscribers_.insert(notice.networkId);
104 FI_HILOGI("Add subscriber for networkId:%{public}s successfully", Utility::Anonymize(notice.networkId).c_str());
105 DSoftbusReplySubscribeMouseLocation event = {
106 .networkId = notice.remoteNetworkId,
107 .remoteNetworkId = notice.networkId,
108 .result = true,
109 };
110 FI_HILOGI("ReplySubscribeMouseLocation from networkId:%{public}s to networkId:%{public}s",
111 Utility::Anonymize(event.networkId).c_str(), Utility::Anonymize(event.remoteNetworkId).c_str());
112 ReplySubscribeMouseLocation(event);
113 }
114
OnUnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation & notice)115 void MouseLocation::OnUnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation ¬ice)
116 {
117 CALL_INFO_TRACE;
118 std::lock_guard<std::mutex> guard(mutex_);
119 localNetworkId_ = IDSoftbusAdapter::GetLocalNetworkId();
120 if (remoteSubscribers_.find(notice.networkId) == remoteSubscribers_.end()) {
121 FI_HILOGE("No subscriber for networkId:%{public}s stored in remote subscriber",
122 Utility::Anonymize(notice.networkId).c_str());
123 return;
124 }
125 remoteSubscribers_.erase(notice.networkId);
126 DSoftbusReplyUnSubscribeMouseLocation event = {
127 .networkId = notice.remoteNetworkId,
128 .remoteNetworkId = notice.networkId,
129 .result = true,
130 };
131 FI_HILOGI("ReplyUnSubscribeMouseLocation from networkId:%{public}s to networkId:%{public}s",
132 Utility::Anonymize(event.networkId).c_str(), Utility::Anonymize(event.remoteNetworkId).c_str());
133 ReplyUnSubscribeMouseLocation(event);
134 }
135
OnReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation & notice)136 void MouseLocation::OnReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation ¬ice)
137 {
138 CALL_INFO_TRACE;
139 std::lock_guard<std::mutex> guard(mutex_);
140 if (notice.result) {
141 FI_HILOGI("SubscribeMouseLocation of networkId:%{public}s successfully, localNetworkId:%{public}s",
142 Utility::Anonymize(notice.networkId).c_str(), Utility::Anonymize(notice.remoteNetworkId).c_str());
143 } else {
144 FI_HILOGI("SubscribeMouseLocation of networkId:%{public}s failed, localNetworkId:%{public}s",
145 Utility::Anonymize(notice.networkId).c_str(), Utility::Anonymize(notice.remoteNetworkId).c_str());
146 }
147 }
148
OnReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation & notice)149 void MouseLocation::OnReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation ¬ice)
150 {
151 CALL_INFO_TRACE;
152 std::lock_guard<std::mutex> guard(mutex_);
153 if (notice.result) {
154 FI_HILOGI("UnSubscribeMouseLocation of networkId:%{public}s successfully, localNetworkId:%{public}s",
155 Utility::Anonymize(notice.networkId).c_str(), Utility::Anonymize(notice.remoteNetworkId).c_str());
156 } else {
157 FI_HILOGI("UnSubscribeMouseLocation of networkId:%{public}s failed, localNetworkId:%{public}s",
158 Utility::Anonymize(notice.networkId).c_str(), Utility::Anonymize(notice.remoteNetworkId).c_str());
159 }
160 }
161
OnRemoteMouseLocation(const DSoftbusSyncMouseLocation & notice)162 void MouseLocation::OnRemoteMouseLocation(const DSoftbusSyncMouseLocation ¬ice)
163 {
164 CALL_DEBUG_ENTER;
165 std::lock_guard<std::mutex> guard(mutex_);
166 if (listeners_.find(notice.networkId) == listeners_.end()) {
167 FI_HILOGE("No listener for networkId:%{public}s stored in listeners",
168 Utility::Anonymize(notice.networkId).c_str());
169 return;
170 }
171 LocationInfo locationInfo {
172 .displayX = notice.mouseLocation.displayX,
173 .displayY = notice.mouseLocation.displayY,
174 .displayWidth = notice.mouseLocation.displayWidth,
175 .displayHeight = notice.mouseLocation.displayHeight
176 };
177 for (auto pid : listeners_[notice.networkId]) {
178 ReportMouseLocationToListener(notice.networkId, locationInfo, pid);
179 }
180 }
181
ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)182 void MouseLocation::ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)
183 {
184 CALL_DEBUG_ENTER;
185 std::lock_guard<std::mutex> guard(mutex_);
186 CHKPV(pointerEvent);
187 if (auto sourceType = pointerEvent->GetSourceType(); sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
188 FI_HILOGD("Unexpected sourceType:%{public}d", static_cast<int32_t>(sourceType));
189 return;
190 }
191 LocationInfo locationInfo;
192 TransferToLocationInfo(pointerEvent, locationInfo);
193 if (HasLocalListener()) {
194 for (auto pid : localListeners_) {
195 ReportMouseLocationToListener(localNetworkId_, locationInfo, pid);
196 }
197 }
198 if (!HasRemoteSubscriber()) {
199 FI_HILOGD("No remote subscriber");
200 return;
201 }
202 for (const auto &networkId : remoteSubscribers_) {
203 SyncLocationToRemote(networkId, locationInfo);
204 }
205 }
206
SyncLocationToRemote(const std::string & remoteNetworkId,const LocationInfo & locationInfo)207 void MouseLocation::SyncLocationToRemote(const std::string &remoteNetworkId, const LocationInfo &locationInfo)
208 {
209 CALL_DEBUG_ENTER;
210 DSoftbusSyncMouseLocation softbusEvent {
211 .networkId = localNetworkId_,
212 .remoteNetworkId = remoteNetworkId,
213 .mouseLocation = {
214 .displayX = locationInfo.displayX,
215 .displayY = locationInfo.displayY,
216 .displayWidth = locationInfo.displayWidth,
217 .displayHeight = locationInfo.displayHeight,
218 },
219 };
220 SyncMouseLocation(softbusEvent);
221 }
222
ReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation & event)223 int32_t MouseLocation::ReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation &event)
224 {
225 CALL_INFO_TRACE;
226 NetPacket packet(MessageId::DSOFTBUS_REPLY_SUBSCRIBE_MOUSE_LOCATION);
227 packet << event.networkId << event.remoteNetworkId << event.result;
228 if (packet.ChkRWError()) {
229 FI_HILOGE("Failed to write data packet");
230 return RET_ERR;
231 }
232 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
233 FI_HILOGE("SendPacket failed");
234 return RET_ERR;
235 }
236 return RET_OK;
237 }
238
ReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation & event)239 int32_t MouseLocation::ReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation &event)
240 {
241 CALL_INFO_TRACE;
242 NetPacket packet(MessageId::DSOFTBUS_REPLY_UNSUBSCRIBE_MOUSE_LOCATION);
243 packet << event.networkId << event.remoteNetworkId << event.result;
244 if (packet.ChkRWError()) {
245 FI_HILOGE("Failed to write data packet");
246 return RET_ERR;
247 }
248 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
249 FI_HILOGE("SendPacket failed");
250 return RET_ERR;
251 }
252 return RET_OK;
253 }
254
SubscribeMouseLocation(const DSoftbusSubscribeMouseLocation & event)255 int32_t MouseLocation::SubscribeMouseLocation(const DSoftbusSubscribeMouseLocation &event)
256 {
257 CALL_INFO_TRACE;
258 NetPacket packet(MessageId::DSOFTBUS_SUBSCRIBE_MOUSE_LOCATION);
259 packet << event.networkId << event.remoteNetworkId;
260 if (packet.ChkRWError()) {
261 FI_HILOGE("Failed to write data packet");
262 return RET_ERR;
263 }
264 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
265 FI_HILOGE("SendPacket failed");
266 return RET_ERR;
267 }
268 return RET_OK;
269 }
270
UnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation & event)271 int32_t MouseLocation::UnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation &event)
272 {
273 CALL_INFO_TRACE;
274 NetPacket packet(MessageId::DSOFTBUS_UNSUBSCRIBE_MOUSE_LOCATION);
275 packet << event.networkId << event.remoteNetworkId;
276 if (packet.ChkRWError()) {
277 FI_HILOGE("Failed to write data packet");
278 return RET_ERR;
279 }
280 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
281 FI_HILOGE("SendPacket failed");
282 return RET_ERR;
283 }
284 return RET_OK;
285 }
286
SyncMouseLocation(const DSoftbusSyncMouseLocation & event)287 int32_t MouseLocation::SyncMouseLocation(const DSoftbusSyncMouseLocation &event)
288 {
289 CALL_DEBUG_ENTER;
290 NetPacket packet(MessageId::DSOFTBUS_MOUSE_LOCATION);
291 packet << event.networkId << event.remoteNetworkId << event.mouseLocation.displayX <<
292 event.mouseLocation.displayY << event.mouseLocation.displayWidth << event.mouseLocation.displayHeight;
293 if (packet.ChkRWError()) {
294 FI_HILOGE("Failed to write data packet");
295 return RET_ERR;
296 }
297 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
298 FI_HILOGE("SendPacket failed");
299 return RET_ERR;
300 }
301 return RET_OK;
302 }
303
ReportMouseLocationToListener(const std::string & networkId,const LocationInfo & locationInfo,int32_t pid)304 void MouseLocation::ReportMouseLocationToListener(const std::string &networkId, const LocationInfo &locationInfo,
305 int32_t pid)
306 {
307 CALL_DEBUG_ENTER;
308 CHKPV(context_);
309 auto session = context_->GetSocketSessionManager().FindSessionByPid(pid);
310 CHKPV(session);
311 NetPacket pkt(MessageId::MOUSE_LOCATION_ADD_LISTENER);
312 pkt << networkId << locationInfo.displayX << locationInfo.displayY <<
313 locationInfo.displayWidth << locationInfo.displayHeight;
314 if (pkt.ChkRWError()) {
315 FI_HILOGE("Packet write data failed");
316 return;
317 }
318 if (!session->SendMsg(pkt)) {
319 FI_HILOGE("Sending failed");
320 return;
321 }
322 }
323
TransferToLocationInfo(std::shared_ptr<MMI::PointerEvent> pointerEvent,LocationInfo & locationInfo)324 void MouseLocation::TransferToLocationInfo(std::shared_ptr<MMI::PointerEvent> pointerEvent, LocationInfo &locationInfo)
325 {
326 CALL_DEBUG_ENTER;
327 CHKPV(pointerEvent);
328 MMI::PointerEvent::PointerItem pointerItem;
329 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
330 FI_HILOGE("Corrupted pointer event");
331 return;
332 }
333 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
334 CHKPV(display);
335 locationInfo = {
336 .displayX = pointerItem.GetDisplayX(),
337 .displayY = pointerItem.GetDisplayY(),
338 .displayWidth = display->GetWidth(),
339 .displayHeight = display->GetHeight(),
340 };
341 }
342
HasRemoteSubscriber()343 bool MouseLocation::HasRemoteSubscriber()
344 {
345 CALL_DEBUG_ENTER;
346 return !remoteSubscribers_.empty();
347 }
348
HasLocalListener()349 bool MouseLocation::HasLocalListener()
350 {
351 CALL_DEBUG_ENTER;
352 return !localListeners_.empty();
353 }
354
SendPacket(const std::string & remoteNetworkId,NetPacket & packet)355 int32_t MouseLocation::SendPacket(const std::string &remoteNetworkId, NetPacket &packet)
356 {
357 CALL_DEBUG_ENTER;
358 CHKPR(context_, RET_ERR);
359 if (context_->GetDSoftbus().OpenSession(remoteNetworkId) != RET_OK) {
360 FI_HILOGE("Failed to connect to %{public}s", Utility::Anonymize(remoteNetworkId).c_str());
361 return RET_ERR;
362 }
363 if (context_->GetDSoftbus().SendPacket(remoteNetworkId, packet) != RET_OK) {
364 FI_HILOGE("SendPacket failed to %{public}s", Utility::Anonymize(remoteNetworkId).c_str());
365 return RET_ERR;
366 }
367 return RET_OK;
368 }
369
370 } // namespace Cooperate
371 } // namespace DeviceStatus
372 } // namespace Msdp
373 } // namespace OHOS