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 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
RemoveListener(const UnregisterEventListenerEvent & event)54 void 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
OnClientDied(const ClientDiedEvent & event)81 void 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
OnSoftbusSessionClosed(const DSoftbusSessionClosed & notice)103 void 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
OnSubscribeMouseLocation(const DSoftbusSubscribeMouseLocation & notice)118 void 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
OnUnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation & notice)135 void 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
OnReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation & notice)156 void 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
OnReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation & notice)169 void 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
OnRemoteMouseLocation(const DSoftbusSyncMouseLocation & notice)182 void 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
ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)202 void 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
SyncLocationToRemote(const std::string & remoteNetworkId,const LocationInfo & locationInfo)227 void 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
ReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation & event)243 int32_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
ReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation & event)259 int32_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
SubscribeMouseLocation(const DSoftbusSubscribeMouseLocation & event)275 int32_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
UnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation & event)291 int32_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
SyncMouseLocation(const DSoftbusSyncMouseLocation & event)307 int32_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
ReportMouseLocationToListener(const std::string & networkId,const LocationInfo & locationInfo,int32_t pid)324 void 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
TransferToLocationInfo(std::shared_ptr<MMI::PointerEvent> pointerEvent,LocationInfo & locationInfo)344 void 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
HasRemoteSubscriber()363 bool MouseLocation::HasRemoteSubscriber()
364 {
365 CALL_DEBUG_ENTER;
366 return !remoteSubscribers_.empty();
367 }
368
HasLocalListener()369 bool MouseLocation::HasLocalListener()
370 {
371 CALL_DEBUG_ENTER;
372 return !localListeners_.empty();
373 }
374
SendPacket(const std::string & remoteNetworkId,NetPacket & packet)375 int32_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