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