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