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