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(
168 "No listener for networkId:%{public}s stored in listeners", Utility::Anonymize(notice.networkId).c_str());
169 return;
170 }
171 LocationInfo locationInfo { .displayX = notice.mouseLocation.displayX,
172 .displayY = notice.mouseLocation.displayY,
173 .displayWidth = notice.mouseLocation.displayWidth,
174 .displayHeight = notice.mouseLocation.displayHeight };
175 for (auto pid : listeners_[notice.networkId]) {
176 ReportMouseLocationToListener(notice.networkId, locationInfo, pid);
177 }
178 }
179
ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)180 void MouseLocation::ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)
181 {
182 CALL_DEBUG_ENTER;
183 std::lock_guard<std::mutex> guard(mutex_);
184 CHKPV(pointerEvent);
185 if (auto sourceType = pointerEvent->GetSourceType(); sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
186 FI_HILOGD("Unexpected sourceType:%{public}d", static_cast<int32_t>(sourceType));
187 return;
188 }
189 LocationInfo locationInfo;
190 TransferToLocationInfo(pointerEvent, locationInfo);
191 if (HasLocalListener()) {
192 for (auto pid : localListeners_) {
193 ReportMouseLocationToListener(localNetworkId_, locationInfo, pid);
194 }
195 }
196 if (!HasRemoteSubscriber()) {
197 FI_HILOGD("No remote subscriber");
198 return;
199 }
200 for (const auto &networkId : remoteSubscribers_) {
201 SyncLocationToRemote(networkId, locationInfo);
202 }
203 }
204
SyncLocationToRemote(const std::string & remoteNetworkId,const LocationInfo & locationInfo)205 void MouseLocation::SyncLocationToRemote(const std::string &remoteNetworkId, const LocationInfo &locationInfo)
206 {
207 CALL_DEBUG_ENTER;
208 DSoftbusSyncMouseLocation softbusEvent {
209 .networkId = localNetworkId_,
210 .remoteNetworkId = remoteNetworkId,
211 .mouseLocation = {
212 .displayX = locationInfo.displayX,
213 .displayY = locationInfo.displayY,
214 .displayWidth = locationInfo.displayWidth,
215 .displayHeight = locationInfo.displayHeight,
216 },
217 };
218 SyncMouseLocation(softbusEvent);
219 }
220
ReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation & event)221 int32_t MouseLocation::ReplySubscribeMouseLocation(const DSoftbusReplySubscribeMouseLocation &event)
222 {
223 CALL_INFO_TRACE;
224 NetPacket packet(MessageId::DSOFTBUS_REPLY_SUBSCRIBE_MOUSE_LOCATION);
225 packet << event.networkId << event.remoteNetworkId << event.result;
226 if (packet.ChkRWError()) {
227 FI_HILOGE("Failed to write data packet");
228 return RET_ERR;
229 }
230 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
231 FI_HILOGE("SendPacket failed");
232 return RET_ERR;
233 }
234 return RET_OK;
235 }
236
ReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation & event)237 int32_t MouseLocation::ReplyUnSubscribeMouseLocation(const DSoftbusReplyUnSubscribeMouseLocation &event)
238 {
239 CALL_INFO_TRACE;
240 NetPacket packet(MessageId::DSOFTBUS_REPLY_UNSUBSCRIBE_MOUSE_LOCATION);
241 packet << event.networkId << event.remoteNetworkId << event.result;
242 if (packet.ChkRWError()) {
243 FI_HILOGE("Failed to write data packet");
244 return RET_ERR;
245 }
246 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
247 FI_HILOGE("SendPacket failed");
248 return RET_ERR;
249 }
250 return RET_OK;
251 }
252
SubscribeMouseLocation(const DSoftbusSubscribeMouseLocation & event)253 int32_t MouseLocation::SubscribeMouseLocation(const DSoftbusSubscribeMouseLocation &event)
254 {
255 CALL_INFO_TRACE;
256 NetPacket packet(MessageId::DSOFTBUS_SUBSCRIBE_MOUSE_LOCATION);
257 packet << event.networkId << event.remoteNetworkId;
258 if (packet.ChkRWError()) {
259 FI_HILOGE("Failed to write data packet");
260 return RET_ERR;
261 }
262 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
263 FI_HILOGE("SendPacket failed");
264 return RET_ERR;
265 }
266 return RET_OK;
267 }
268
UnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation & event)269 int32_t MouseLocation::UnSubscribeMouseLocation(const DSoftbusUnSubscribeMouseLocation &event)
270 {
271 CALL_INFO_TRACE;
272 NetPacket packet(MessageId::DSOFTBUS_UNSUBSCRIBE_MOUSE_LOCATION);
273 packet << event.networkId << event.remoteNetworkId;
274 if (packet.ChkRWError()) {
275 FI_HILOGE("Failed to write data packet");
276 return RET_ERR;
277 }
278 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
279 FI_HILOGE("SendPacket failed");
280 return RET_ERR;
281 }
282 return RET_OK;
283 }
284
SyncMouseLocation(const DSoftbusSyncMouseLocation & event)285 int32_t MouseLocation::SyncMouseLocation(const DSoftbusSyncMouseLocation &event)
286 {
287 CALL_DEBUG_ENTER;
288 NetPacket packet(MessageId::DSOFTBUS_MOUSE_LOCATION);
289 packet << event.networkId << event.remoteNetworkId << event.mouseLocation.displayX << event.mouseLocation.displayY
290 << event.mouseLocation.displayWidth << event.mouseLocation.displayHeight;
291 if (packet.ChkRWError()) {
292 FI_HILOGE("Failed to write data packet");
293 return RET_ERR;
294 }
295 if (SendPacket(event.remoteNetworkId, packet) != RET_OK) {
296 FI_HILOGE("SendPacket failed");
297 return RET_ERR;
298 }
299 return RET_OK;
300 }
301
ReportMouseLocationToListener(const std::string & networkId,const LocationInfo & locationInfo,int32_t pid)302 void MouseLocation::ReportMouseLocationToListener(
303 const std::string &networkId, const LocationInfo &locationInfo, int32_t pid)
304 {
305 CALL_DEBUG_ENTER;
306 CHKPV(context_);
307 auto session = context_->GetSocketSessionManager().FindSessionByPid(pid);
308 CHKPV(session);
309 NetPacket pkt(MessageId::MOUSE_LOCATION_ADD_LISTENER);
310 pkt << networkId << locationInfo.displayX << locationInfo.displayY << locationInfo.displayWidth
311 << locationInfo.displayHeight;
312 if (pkt.ChkRWError()) {
313 FI_HILOGE("Packet write data failed");
314 return;
315 }
316 if (!session->SendMsg(pkt)) {
317 FI_HILOGE("Sending failed");
318 return;
319 }
320 }
321
TransferToLocationInfo(std::shared_ptr<MMI::PointerEvent> pointerEvent,LocationInfo & locationInfo)322 void MouseLocation::TransferToLocationInfo(std::shared_ptr<MMI::PointerEvent> pointerEvent, LocationInfo &locationInfo)
323 {
324 CALL_DEBUG_ENTER;
325 CHKPV(pointerEvent);
326 MMI::PointerEvent::PointerItem pointerItem;
327 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
328 FI_HILOGE("Corrupted pointer event");
329 return;
330 }
331 auto display = Rosen::DisplayManagerLite::GetInstance().GetDefaultDisplay();
332 CHKPV(display);
333 locationInfo = {
334 .displayX = pointerItem.GetDisplayX(),
335 .displayY = pointerItem.GetDisplayY(),
336 .displayWidth = display->GetWidth(),
337 .displayHeight = display->GetHeight(),
338 };
339 }
340
HasRemoteSubscriber()341 bool MouseLocation::HasRemoteSubscriber()
342 {
343 CALL_DEBUG_ENTER;
344 return !remoteSubscribers_.empty();
345 }
346
HasLocalListener()347 bool MouseLocation::HasLocalListener()
348 {
349 CALL_DEBUG_ENTER;
350 return !localListeners_.empty();
351 }
352
SendPacket(const std::string & remoteNetworkId,NetPacket & packet)353 int32_t MouseLocation::SendPacket(const std::string &remoteNetworkId, NetPacket &packet)
354 {
355 CALL_DEBUG_ENTER;
356 CHKPR(context_, RET_ERR);
357 if (context_->GetDSoftbus().OpenSession(remoteNetworkId) != RET_OK) {
358 FI_HILOGE("Failed to connect to %{public}s", Utility::Anonymize(remoteNetworkId).c_str());
359 return RET_ERR;
360 }
361 if (context_->GetDSoftbus().SendPacket(remoteNetworkId, packet) != RET_OK) {
362 FI_HILOGE("SendPacket failed to %{public}s", Utility::Anonymize(remoteNetworkId).c_str());
363 return RET_ERR;
364 }
365 return RET_OK;
366 }
367
368 } // namespace Cooperate
369 } // namespace DeviceStatus
370 } // namespace Msdp
371 } // namespace OHOS
372