• 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 "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