• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &notice)
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 &notice)
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 &notice)
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 &notice)
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 &notice)
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