• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 "cooperate_client.h"
17 #include "cooperate_hisysevent.h"
18 
19 #ifdef ENABLE_PERFORMANCE_CHECK
20 #include <algorithm>
21 #include <numeric>
22 #endif // ENABLE_PERFORMANCE_CHECK
23 
24 #include "cooperate_params.h"
25 #include "default_params.h"
26 #include "devicestatus_define.h"
27 #include "utility.h"
28 
29 #undef LOG_TAG
30 #define LOG_TAG "CooperateClient"
31 
32 namespace OHOS {
33 namespace Msdp {
34 namespace DeviceStatus {
35 namespace {
36 #ifdef ENABLE_PERFORMANCE_CHECK
37 constexpr int32_t PERCENTAGE { 100 };
38 constexpr int32_t FAILURE_DURATION { -100 };
39 constexpr int32_t INVALID_INDEX { -1 };
40 #endif // ENABLE_PERFORMANCE_CHECK
41 } // namespace
42 
RegisterListener(ITunnelClient & tunnel,CooperateListenerPtr listener,bool isCheckPermission)43 int32_t CooperateClient::RegisterListener(ITunnelClient &tunnel,
44     CooperateListenerPtr listener, bool isCheckPermission)
45 {
46     CALL_DEBUG_ENTER;
47     CHKPR(listener, RET_ERR);
48     std::lock_guard<std::mutex> guard(mtx_);
49     for (const auto &item : devCooperateListener_) {
50         if (item == listener) {
51             FI_HILOGE("The listener already exists");
52             return RET_ERR;
53         }
54     }
55     if (!isListeningProcess_) {
56         FI_HILOGI("Start monitoring");
57         DefaultParam param;
58         DefaultReply reply;
59 
60         int32_t ret = tunnel.AddWatch(Intention::COOPERATE, CooperateRequestID::REGISTER_LISTENER, param, reply);
61         if (ret != RET_OK) {
62             FI_HILOGE("Failed to register, ret:%{public}d", ret);
63             return ret;
64         }
65         isListeningProcess_ = true;
66     }
67     devCooperateListener_.push_back(listener);
68     return RET_OK;
69 }
70 
UnregisterListener(ITunnelClient & tunnel,CooperateListenerPtr listener,bool isCheckPermission)71 int32_t CooperateClient::UnregisterListener(ITunnelClient &tunnel,
72     CooperateListenerPtr listener, bool isCheckPermission)
73 {
74     CALL_DEBUG_ENTER;
75     std::lock_guard<std::mutex> guard(mtx_);
76     if (listener == nullptr) {
77         devCooperateListener_.clear();
78         goto listenerLabel;
79     }
80     for (auto it = devCooperateListener_.begin(); it != devCooperateListener_.end(); ++it) {
81         if (*it == listener) {
82             devCooperateListener_.erase(it);
83             goto listenerLabel;
84         }
85     }
86 
87 listenerLabel:
88     if (isListeningProcess_ && devCooperateListener_.empty()) {
89         isListeningProcess_ = false;
90         DefaultParam param;
91         DefaultReply reply;
92         return tunnel.RemoveWatch(Intention::COOPERATE, CooperateRequestID::UNREGISTER_LISTENER, param, reply);
93     }
94     return RET_OK;
95 }
96 
Enable(ITunnelClient & tunnel,CooperateMessageCallback callback,bool isCheckPermission)97 int32_t CooperateClient::Enable(ITunnelClient &tunnel,
98     CooperateMessageCallback callback, bool isCheckPermission)
99 {
100     CALL_DEBUG_ENTER;
101     std::lock_guard<std::mutex> guard(mtx_);
102     CooperateEvent event { callback };
103     DefaultParam param { GenerateRequestID() };
104     DefaultReply reply;
105 
106     int32_t ret = tunnel.Enable(Intention::COOPERATE, param, reply);
107     if (ret != RET_OK) {
108         FI_HILOGE("Prepare cooperate failed");
109         return ret;
110     }
111     devCooperateEvent_.insert_or_assign(param.userData, event);
112     return RET_OK;
113 }
114 
Disable(ITunnelClient & tunnel,CooperateMessageCallback callback,bool isCheckPermission)115 int32_t CooperateClient::Disable(ITunnelClient &tunnel,
116     CooperateMessageCallback callback, bool isCheckPermission)
117 {
118     CALL_DEBUG_ENTER;
119     std::lock_guard<std::mutex> guard(mtx_);
120     CooperateEvent event { callback };
121     DefaultParam param { GenerateRequestID() };
122     DefaultReply reply;
123 
124     int32_t ret = tunnel.Disable(Intention::COOPERATE, param, reply);
125     if (ret != RET_OK) {
126         FI_HILOGE("Unprepare cooperate failed");
127         return ret;
128     }
129     devCooperateEvent_.insert_or_assign(param.userData, event);
130 #ifdef ENABLE_PERFORMANCE_CHECK
131     DumpPerformanceInfo();
132 #endif // ENABLE_PERFORMANCE_CHECK
133     return RET_OK;
134 }
135 
Start(ITunnelClient & tunnel,const std::string & remoteNetworkId,int32_t startDeviceId,CooperateMessageCallback callback,bool isCheckPermission)136 int32_t CooperateClient::Start(ITunnelClient &tunnel, const std::string &remoteNetworkId,
137     int32_t startDeviceId, CooperateMessageCallback callback, bool isCheckPermission)
138 {
139     CALL_DEBUG_ENTER;
140     std::lock_guard<std::mutex> guard(mtx_);
141     CooperateEvent event { callback };
142     auto userData = GenerateRequestID();
143 #ifdef ENABLE_PERFORMANCE_CHECK
144     StartTrace(userData);
145 #endif // ENABLE_PERFORMANCE_CHECK
146     CooperateParamType paramType = CooperateParamType::DEFAULT;
147     CooperateOptions options;
148     StartCooperateParam param { userData, remoteNetworkId, startDeviceId, isCheckPermission, options,
149         static_cast<int32_t>(paramType) };
150     DefaultReply reply;
151 
152     int32_t ret = tunnel.Start(Intention::COOPERATE, param, reply);
153     if (ret != RET_OK) {
154         FI_HILOGE("Activate cooperate failed");
155         return ret;
156     }
157     devCooperateEvent_.insert_or_assign(param.userData, event);
158     return RET_OK;
159 }
160 
StartWithOptions(ITunnelClient & tunnel,const std::string & remoteNetworkId,int32_t startDeviceId,CooperateMessageCallback callback,const CooperateOptions & options)161 int32_t CooperateClient::StartWithOptions(ITunnelClient &tunnel, const std::string &remoteNetworkId,
162     int32_t startDeviceId, CooperateMessageCallback callback, const CooperateOptions &options)
163 {
164     CALL_DEBUG_ENTER;
165     std::lock_guard<std::mutex> guard(mtx_);
166     CooperateEvent event { callback };
167     auto userData = GenerateRequestID();
168 #ifdef ENABLE_PERFORMANCE_CHECK
169     StartTrace(userData);
170 #endif // ENABLE_PERFORMANCE_CHECK
171     CooperateParamType paramType = CooperateParamType::WITHOPTIONS;
172     bool isCheckPermission = false;
173     StartCooperateParam param { userData, remoteNetworkId, startDeviceId, isCheckPermission, options,
174         static_cast<int32_t>(paramType) };
175     DefaultReply reply;
176 
177     int32_t ret = tunnel.Start(Intention::COOPERATE, param, reply);
178     if (ret != RET_OK) {
179         FI_HILOGE("Activate cooperate failed");
180         return ret;
181     }
182     devCooperateEvent_.insert_or_assign(param.userData, event);
183     return RET_OK;
184 }
185 
Stop(ITunnelClient & tunnel,bool isUnchained,CooperateMessageCallback callback,bool isCheckPermission)186 int32_t CooperateClient::Stop(ITunnelClient &tunnel,
187     bool isUnchained, CooperateMessageCallback callback, bool isCheckPermission)
188 {
189     CALL_DEBUG_ENTER;
190     std::lock_guard<std::mutex> guard(mtx_);
191     CooperateEvent event { callback };
192     StopCooperateParam param { GenerateRequestID(), isUnchained, isCheckPermission };
193     DefaultReply reply;
194 
195     int32_t ret = tunnel.Stop(Intention::COOPERATE, param, reply);
196     if (ret != RET_OK) {
197         FI_HILOGE("Deactivate cooperate failed");
198         return ret;
199     }
200     devCooperateEvent_.insert_or_assign(param.userData, event);
201     return RET_OK;
202 }
203 
GetCooperateState(ITunnelClient & tunnel,const std::string & networkId,CooperateStateCallback callback,bool isCheckPermission)204 int32_t CooperateClient::GetCooperateState(ITunnelClient &tunnel,
205     const std::string &networkId, CooperateStateCallback callback, bool isCheckPermission)
206 {
207     CALL_DEBUG_ENTER;
208     std::lock_guard<std::mutex> guard(mtx_);
209     CooperateEvent event { callback };
210     GetCooperateStateParam param { GenerateRequestID(), networkId, isCheckPermission };
211     DefaultReply reply;
212 
213     int32_t ret = tunnel.GetParam(Intention::COOPERATE, CooperateRequestID::GET_COOPERATE_STATE, param, reply);
214     if (ret != RET_OK) {
215         FI_HILOGE("Get cooperate state failed");
216         return ret;
217     }
218     devCooperateEvent_.insert_or_assign(param.userData, event);
219     return RET_OK;
220 }
221 
GetCooperateState(ITunnelClient & tunnel,const std::string & udId,bool & state)222 int32_t CooperateClient::GetCooperateState(ITunnelClient &tunnel, const std::string &udId, bool &state)
223 {
224     CALL_DEBUG_ENTER;
225     std::lock_guard<std::mutex> guard(mtx_);
226     GetCooperateStateSyncParam param { udId };
227     BooleanReply reply;
228     if (tunnel.GetParam(Intention::COOPERATE, CooperateRequestID::GET_COOPERATE_STATE_SYNC, param, reply) != RET_OK) {
229         FI_HILOGE("Get cooperate state failed udId: %{public}s", Utility::Anonymize(udId).c_str());
230         return RET_ERR;
231     }
232     FI_HILOGI("GetCooperateState for udId: %{public}s successfully,state: %{public}s",
233         Utility::Anonymize(udId).c_str(), reply.state ? "true" : "false");
234     state = reply.state;
235     return RET_OK;
236 }
237 
RegisterEventListener(ITunnelClient & tunnel,const std::string & networkId,MouseLocationListenerPtr listener)238 int32_t CooperateClient::RegisterEventListener(ITunnelClient &tunnel,
239     const std::string &networkId, MouseLocationListenerPtr listener)
240 {
241     CALL_DEBUG_ENTER;
242     CHKPR(listener, COMMON_PARAMETER_ERROR);
243     std::lock_guard<std::mutex> guard(mtx_);
244     if (eventListener_.find(networkId) != eventListener_.end() &&
245         eventListener_[networkId].find(listener) != eventListener_[networkId].end()) {
246         FI_HILOGE("This listener for networkId:%{public}s already exists", Utility::Anonymize(networkId).c_str());
247         return RET_ERR;
248     }
249     RegisterEventListenerParam param { networkId };
250     DefaultReply reply;
251     if (int32_t ret = tunnel.AddWatch(Intention::COOPERATE, CooperateRequestID::REGISTER_EVENT_LISTENER, param, reply);
252         ret != RET_OK) {
253         FI_HILOGE("RegisterEventListener failed, ret:%{public}d", ret);
254         return ret;
255     }
256     eventListener_[networkId].insert(listener);
257     FI_HILOGI("Add listener for networkId:%{public}s successfully", Utility::Anonymize(networkId).c_str());
258     return RET_OK;
259 }
260 
UnregisterEventListener(ITunnelClient & tunnel,const std::string & networkId,MouseLocationListenerPtr listener)261 int32_t CooperateClient::UnregisterEventListener(ITunnelClient &tunnel,
262     const std::string &networkId, MouseLocationListenerPtr listener)
263 {
264     CALL_DEBUG_ENTER;
265     std::lock_guard<std::mutex> guard(mtx_);
266     if (eventListener_.find(networkId) == eventListener_.end()) {
267         FI_HILOGE("No listener for networkId:%{public}s is registered", Utility::Anonymize(networkId).c_str());
268         return RET_ERR;
269     }
270     if (eventListener_.find(networkId) != eventListener_.end() && listener != nullptr &&
271         eventListener_[networkId].find(listener) == eventListener_[networkId].end()) {
272         FI_HILOGE("Current listener for networkId:%{public}s is not registered", Utility::Anonymize(networkId).c_str());
273         return RET_ERR;
274     }
275     if (listener == nullptr) {
276         eventListener_.erase(networkId);
277         FI_HILOGI("Remove all listener for networkId:%{public}s", Utility::Anonymize(networkId).c_str());
278     } else {
279         eventListener_[networkId].erase(listener);
280         FI_HILOGI("Remove listener for networkId:%{public}s", Utility::Anonymize(networkId).c_str());
281         if (eventListener_[networkId].empty()) {
282             eventListener_.erase(networkId);
283             FI_HILOGD("No listener for networkId:%{public}s, clean current networkId",
284                 Utility::Anonymize(networkId).c_str());
285         }
286     }
287     if (eventListener_.find(networkId) != eventListener_.end()) {
288         FI_HILOGD("UnregisterEventListener for networkId:%{public}s successfully",
289             Utility::Anonymize(networkId).c_str());
290         return RET_OK;
291     }
292     UnregisterEventListenerParam param { networkId };
293     DefaultReply reply;
294     if (int32_t ret = tunnel.RemoveWatch(Intention::COOPERATE,
295         CooperateRequestID::UNREGISTER_EVENT_LISTENER, param, reply); ret != RET_OK) {
296         FI_HILOGE("UnregisterEventListener failed, ret:%{public}d", ret);
297         return ret;
298     }
299     FI_HILOGD("Unregister all Listener for networkId:%{public}s successfully", Utility::Anonymize(networkId).c_str());
300     return RET_OK;
301 }
302 
SetDamplingCoefficient(ITunnelClient & tunnel,uint32_t direction,double coefficient)303 int32_t CooperateClient::SetDamplingCoefficient(ITunnelClient &tunnel, uint32_t direction, double coefficient)
304 {
305     FI_HILOGI("SetDamplingCoefficient(0x%{public}x, %{public}.3f)", direction, coefficient);
306     SetDamplingCoefficientParam param { direction, coefficient };
307     DefaultReply reply;
308 
309     auto ret = tunnel.SetParam(Intention::COOPERATE, CooperateRequestID::SET_DAMPLING_COEFFICIENT, param, reply);
310     if (ret != RET_OK) {
311         FI_HILOGE("ITunnelClient::SetParam fail, error:%{public}d", ret);
312     }
313     return ret;
314 }
315 
AddHotAreaListener(ITunnelClient & tunnel,HotAreaListenerPtr listener)316 int32_t CooperateClient::AddHotAreaListener(ITunnelClient &tunnel, HotAreaListenerPtr listener)
317 {
318     CALL_DEBUG_ENTER;
319     CHKPR(listener, RET_ERR);
320     std::lock_guard<std::mutex> guard(mtx_);
321     if (std::find(devHotAreaListener_.begin(), devHotAreaListener_.end(), listener) != devHotAreaListener_.end()) {
322         FI_HILOGD("Current listener is registered already");
323         return RET_ERR;
324     }
325     RegisterHotAreaListenerParam param { GenerateRequestID(), false };
326     DefaultReply reply;
327     if (int32_t ret = tunnel.AddWatch(Intention::COOPERATE,
328         CooperateRequestID::REGISTER_HOTAREA_LISTENER, param, reply); ret != RET_OK) {
329         FI_HILOGE("AddHotAreaListener failed, ret:%{public}d", ret);
330         return ret;
331     }
332     devHotAreaListener_.push_back(listener);
333     return RET_OK;
334 }
335 
RemoveHotAreaListener(ITunnelClient & tunnel,HotAreaListenerPtr listener)336 int32_t CooperateClient::RemoveHotAreaListener(ITunnelClient &tunnel, HotAreaListenerPtr listener)
337 {
338     CALL_DEBUG_ENTER;
339     {
340         std::lock_guard<std::mutex> guard(mtx_);
341         if (listener != nullptr &&
342             std::find(devHotAreaListener_.begin(), devHotAreaListener_.end(), listener) == devHotAreaListener_.end()) {
343             FI_HILOGD("Current listener is not registered");
344             return RET_ERR;
345         }
346         if (listener == nullptr) {
347             devHotAreaListener_.clear();
348         } else {
349             for (auto it = devHotAreaListener_.begin(); it != devHotAreaListener_.end(); ++it) {
350                 if (*it == listener) {
351                     devHotAreaListener_.erase(it);
352                 }
353             }
354         }
355         if (!devHotAreaListener_.empty()) {
356             FI_HILOGI("RemoveHotAreaListener successfully");
357             return RET_OK;
358         }
359     }
360     UnregisterHotAreaListenerParam param { GenerateRequestID(), false };
361     DefaultReply reply;
362     if (int32_t ret = tunnel.RemoveWatch(Intention::COOPERATE,
363         CooperateRequestID::UNREGISTER_HOTAREA_LISTENER, param, reply); ret != RET_OK) {
364         FI_HILOGE("RemoveHotAreaListener failed, ret:%{public}d", ret);
365         return ret;
366     }
367     FI_HILOGI("Remove all hot area listener successfully");
368     return RET_OK;
369 }
370 
GenerateRequestID()371 int32_t CooperateClient::GenerateRequestID()
372 {
373     static int32_t requestId { 0 };
374 
375     if (requestId == std::numeric_limits<int32_t>::max()) {
376         FI_HILOGE("Request ID exceeds the maximum");
377         requestId = 0;
378     }
379     return requestId++;
380 }
381 
OnCoordinationListener(const StreamClient & client,NetPacket & pkt)382 int32_t CooperateClient::OnCoordinationListener(const StreamClient &client, NetPacket &pkt)
383 {
384     CALL_INFO_TRACE;
385     int32_t userData = 0;
386     std::string networkId;
387     int32_t nType = 0;
388     pkt >> userData >> networkId >> nType;
389     if (pkt.ChkRWError()) {
390         FI_HILOGE("Packet read type failed");
391         return RET_ERR;
392     }
393     FI_HILOGI("NetworkId:%{public}s, nType:%{public}d", Utility::Anonymize(networkId).c_str(), nType);
394     OnDevCooperateListener(networkId, CoordinationMessage(nType));
395     return RET_OK;
396 }
397 
OnDevCooperateListener(const std::string & networkId,CoordinationMessage msg)398 void CooperateClient::OnDevCooperateListener(const std::string &networkId, CoordinationMessage msg)
399 {
400     CALL_INFO_TRACE;
401     std::lock_guard<std::mutex> guard(mtx_);
402     for (const auto &item : devCooperateListener_) {
403         item->OnCoordinationMessage(networkId, msg);
404     }
405 }
406 
OnCoordinationMessage(const StreamClient & client,NetPacket & pkt)407 int32_t CooperateClient::OnCoordinationMessage(const StreamClient &client, NetPacket &pkt)
408 {
409     CALL_INFO_TRACE;
410     int32_t userData = 0;
411     std::string networkId;
412     int32_t nType = 0;
413     int32_t errCode = -1;
414     pkt >> userData >> networkId >> nType >> errCode;
415     if (pkt.ChkRWError()) {
416         FI_HILOGE("Packet read coordination msg failed");
417         return RET_ERR;
418     }
419 #ifdef ENABLE_PERFORMANCE_CHECK
420     FinishTrace(userData, CoordinationMessage(nType));
421 #endif // ENABLE_PERFORMANCE_CHECK
422     FI_HILOGI("NetworkId:%{public}s, nType:%{public}d", Utility::Anonymize(networkId).c_str(), nType);
423     CoordinationMsgInfo msgInfo {
424         .msg = static_cast<CoordinationMessage> (nType),
425         .errCode = errCode
426     };
427     OnCooperateMessageEvent(userData, networkId, msgInfo);
428     auto stageRes = BizCooperateStageRes::RES_IDLE;
429     CooperateRadarInfo radarInfo {
430         .funcName = __FUNCTION__,
431         .bizState = static_cast<int32_t> (BizState::STATE_END),
432         .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_CLIENT_ON_MESSAGE_RCVD),
433         .stageRes = static_cast<int32_t> (stageRes),
434         .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
435         .errCode = static_cast<int32_t> (msgInfo.errCode),
436         .hostName = "",
437         .localNetId = "",
438         .peerNetId = Utility::DFXRadarAnonymize(networkId.c_str())
439     };
440     if (CoordinationMessage(nType) == CoordinationMessage::ACTIVATE_SUCCESS) {
441         stageRes = BizCooperateStageRes::RES_SUCCESS;
442         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
443     } else if (CoordinationMessage(nType) == CoordinationMessage::ACTIVATE_FAIL) {
444         stageRes = BizCooperateStageRes::RES_FAIL;
445         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
446     }
447     return RET_OK;
448 }
449 
OnCooperateMessageEvent(int32_t userData,const std::string & networkId,const CoordinationMsgInfo & msgInfo)450 void CooperateClient::OnCooperateMessageEvent(int32_t userData,
451     const std::string &networkId, const CoordinationMsgInfo &msgInfo)
452 {
453     CALL_INFO_TRACE;
454     CHK_PID_AND_TID();
455     std::lock_guard<std::mutex> guard(mtx_);
456     auto iter = devCooperateEvent_.find(userData);
457     if (iter == devCooperateEvent_.end()) {
458         return;
459     }
460     CooperateMessageCallback callback = iter->second.msgCb;
461     CHKPV(callback);
462     callback(networkId, msgInfo);
463     devCooperateEvent_.erase(iter);
464 }
465 
OnCoordinationState(const StreamClient & client,NetPacket & pkt)466 int32_t CooperateClient::OnCoordinationState(const StreamClient &client, NetPacket &pkt)
467 {
468     CALL_INFO_TRACE;
469     int32_t userData = 0;
470     bool state = false;
471     int32_t errCode = -1;
472     pkt >> userData >> state >> errCode;
473     if (pkt.ChkRWError()) {
474         FI_HILOGE("Packet read coordination msg failed");
475         return RET_ERR;
476     }
477     FI_HILOGI("State%{public}s", state ? "true" : "false");
478     OnCooperateStateEvent(userData, state);
479     return RET_OK;
480 }
481 
OnCooperateStateEvent(int32_t userData,bool state)482 void CooperateClient::OnCooperateStateEvent(int32_t userData, bool state)
483 {
484     CALL_INFO_TRACE;
485     CHK_PID_AND_TID();
486     std::lock_guard<std::mutex> guard(mtx_);
487     auto iter = devCooperateEvent_.find(userData);
488     if (iter == devCooperateEvent_.end()) {
489         return;
490     }
491     CooperateStateCallback event = iter->second.stateCb;
492     CHKPV(event);
493     event(state);
494     devCooperateEvent_.erase(iter);
495     FI_HILOGD("Coordination state event callback, userData:%{public}d, state:(%{public}d)", userData, state);
496 }
497 
OnHotAreaListener(const StreamClient & client,NetPacket & pkt)498 int32_t CooperateClient::OnHotAreaListener(const StreamClient &client, NetPacket &pkt)
499 {
500     CALL_DEBUG_ENTER;
501     int32_t positionX = 0;
502     int32_t positionY = 0;
503     int32_t type = 0;
504     bool isEdge = false;
505     pkt >> positionX >> positionY >> type >> isEdge;
506     if (pkt.ChkRWError()) {
507         FI_HILOGE("Packet read type failed");
508         return RET_ERR;
509     }
510     OnDevHotAreaListener(positionX, positionY, HotAreaType(type), isEdge);
511     return RET_OK;
512 }
513 
OnMouseLocationListener(const StreamClient & client,NetPacket & pkt)514 int32_t CooperateClient::OnMouseLocationListener(const StreamClient &client, NetPacket &pkt)
515 {
516     CALL_DEBUG_ENTER;
517     std::string networkId;
518     Event event;
519     pkt >> networkId >> event.displayX >> event.displayY >> event.displayWidth >> event.displayHeight;
520     if (pkt.ChkRWError()) {
521         FI_HILOGE("Packet read type failed");
522         return RET_ERR;
523     }
524     OnDevMouseLocationListener(networkId, event);
525     return RET_OK;
526 }
527 
OnDevHotAreaListener(int32_t displayX,int32_t displayY,HotAreaType type,bool isEdge)528 void CooperateClient::OnDevHotAreaListener(int32_t displayX,
529     int32_t displayY, HotAreaType type, bool isEdge)
530 {
531     CALL_DEBUG_ENTER;
532     std::lock_guard<std::mutex> guard(mtx_);
533     for (const auto &item : devHotAreaListener_) {
534         item->OnHotAreaMessage(displayX, displayY, type, isEdge);
535     }
536 }
537 
OnDevMouseLocationListener(const std::string & networkId,const Event & event)538 void CooperateClient::OnDevMouseLocationListener(const std::string &networkId, const Event &event)
539 {
540     CALL_DEBUG_ENTER;
541     std::lock_guard<std::mutex> guard(mtx_);
542     if (eventListener_.find(networkId) == eventListener_.end()) {
543         FI_HILOGI("No listener for networkId:%{public}s is registered", Utility::Anonymize(networkId).c_str());
544         return;
545     }
546     for (const auto &listener : eventListener_[networkId]) {
547             CHKPC(listener);
548             listener->OnMouseLocationEvent(networkId, event);
549             FI_HILOGD("Trigger listener for networkId:%{public}s,"
550             "displayX:%{private}d, displayY:%{private}d, displayWidth:%{public}d, displayHeight:%{public}d",
551                 Utility::Anonymize(networkId).c_str(), event.displayX, event.displayY,
552                 event.displayWidth, event.displayHeight);
553     }
554 }
555 
556 #ifdef ENABLE_PERFORMANCE_CHECK
GetFirstSuccessIndex()557 int32_t CooperateClient::GetFirstSuccessIndex()
558 {
559     CALL_DEBUG_ENTER;
560     size_t durationLen =  performanceInfo_.durationList.size();
561     for (size_t i = 0; i < durationLen; ++i) {
562         if (performanceInfo_.durationList[i] != FAILURE_DURATION) {
563             performanceInfo_.successNum = 1;
564             FI_HILOGI("[PERF] First success index:%{public}zu", i);
565             return static_cast<int32_t>(i);
566         }
567     }
568     return INVALID_INDEX;
569 }
StartTrace(int32_t userData)570 void CooperateClient::StartTrace(int32_t userData)
571 {
572     CALL_DEBUG_ENTER;
573     std::lock_guard guard { performanceLock_ };
574     performanceInfo_.traces_.emplace(userData, std::chrono::steady_clock::now());
575     performanceInfo_.activateNum += 1;
576     FI_HILOGI("[PERF] Start tracing \'%{public}d\'", userData);
577 }
578 
FinishTrace(int32_t userData,CoordinationMessage msg)579 void CooperateClient::FinishTrace(int32_t userData, CoordinationMessage msg)
580 {
581     CALL_DEBUG_ENTER;
582     std::lock_guard guard { performanceLock_ };
583     if (msg == CoordinationMessage::ACTIVATE_SUCCESS) {
584         if (auto iter = performanceInfo_.traces_.find(userData); iter != performanceInfo_.traces_.end()) {
585             auto curDuration = std::chrono::duration_cast<std::chrono::milliseconds>(
586                 std::chrono::steady_clock::now() - iter->second).count();
587             FI_HILOGI("[PERF] Finish tracing \'%{public}d\', elapsed: %{public}lld ms", userData, curDuration);
588             performanceInfo_.traces_.erase(iter);
589             performanceInfo_.durationList.push_back(curDuration);
590         } else {
591             FI_HILOGW("[PERF] FinishTrace with something wrong");
592         }
593     } else if (msg == CoordinationMessage::ACTIVATE_FAIL) {
594         FI_HILOGW("[PERF] Activate coordination failed");
595         performanceInfo_.traces_.erase(userData);
596         performanceInfo_.durationList.push_back(FAILURE_DURATION);
597     }
598 }
599 
DumpPerformanceInfo()600 void CooperateClient::DumpPerformanceInfo()
601 {
602     CALL_DEBUG_ENTER;
603     std::lock_guard guard { performanceLock_ };
604     int32_t firstSuccessIndex = GetFirstSuccessIndex();
605     int32_t durationLen = static_cast<int32_t>(performanceInfo_.durationList.size());
606     if (firstSuccessIndex < 0 || firstSuccessIndex >= durationLen) {
607         FI_HILOGE("[PERF] DumpPerformanceInfo failed, invalid first success index");
608         return;
609     }
610     performanceInfo_.failNum = firstSuccessIndex;
611     performanceInfo_.failBeforeSuccess = firstSuccessIndex;
612     performanceInfo_.firstSuccessDuration = performanceInfo_.durationList[firstSuccessIndex];
613     int32_t successDurationSumWithoutFirst { 0 };
614     for (int32_t i = firstSuccessIndex + 1; i < durationLen; i++) {
615         if (performanceInfo_.durationList[i] != FAILURE_DURATION) {
616             successDurationSumWithoutFirst += performanceInfo_.durationList[i];
617             performanceInfo_.minDuration = std::min(performanceInfo_.durationList[i], performanceInfo_.minDuration);
618             performanceInfo_.maxDuration = std::max(performanceInfo_.durationList[i], performanceInfo_.maxDuration);
619             performanceInfo_.successNum += 1;
620         } else {
621             performanceInfo_.failNum += 1;
622         }
623     }
624     int32_t validActivateNum = performanceInfo_.activateNum - performanceInfo_.failBeforeSuccess;
625     if (validActivateNum > 0) {
626         performanceInfo_.successRate = (static_cast<float>(performanceInfo_.successNum) * PERCENTAGE) /
627             validActivateNum;
628     }
629     if (int32_t successNumWithoutFirst = performanceInfo_.successNum - 1; successNumWithoutFirst > 0) {
630         performanceInfo_.averageDuration = successDurationSumWithoutFirst / successNumWithoutFirst;
631     }
632     FI_HILOGI("[PERF] performanceInfo:"
633         "activateNum:%{public}d successNum:%{public}d failNum:%{public}d successRate:%{public}.2f "
634         "averageDuration:%{public}d ms maxDuration:%{public}d ms minDuration:%{public}d ms failBeforeSucc:%{public}d "
635         "firstSuccessDuration:%{public}d ms",
636         performanceInfo_.activateNum, performanceInfo_.successNum, performanceInfo_.failNum,
637         performanceInfo_.successRate, performanceInfo_.averageDuration, performanceInfo_.maxDuration,
638         performanceInfo_.minDuration, performanceInfo_.failBeforeSuccess, performanceInfo_.firstSuccessDuration);
639     std::string durationStr;
640     for (auto duration : performanceInfo_.durationList) {
641         durationStr += std::to_string(duration) + ", ";
642     }
643     FI_HILOGI("[PERF] Duration: %{public}s", durationStr.c_str());
644     performanceInfo_ = PerformanceInfo();
645 }
646 #endif // ENABLE_PERFORMANCE_CHECK
647 } // namespace DeviceStatus
648 } // namespace Msdp
649 } // namespace OHOS
650