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 }
312 }
313 }
314 if (!devHotAreaListener_.empty()) {
315 FI_HILOGI("RemoveHotAreaListener successfully");
316 return RET_OK;
317 }
318 UnregisterHotAreaListenerParam param { GenerateRequestID(), false };
319 DefaultReply reply;
320 if (int32_t ret =
321 tunnel.RemoveWatch(Intention::COOPERATE, CooperateRequestID::UNREGISTER_HOTAREA_LISTENER, param, reply);
322 ret != RET_OK) {
323 FI_HILOGE("RemoveHotAreaListener failed, ret:%{public}d", ret);
324 return ret;
325 }
326 FI_HILOGI("Remove all hot area listener successfully");
327 return RET_OK;
328 }
329
GenerateRequestID()330 int32_t CooperateClient::GenerateRequestID()
331 {
332 static int32_t requestId { 0 };
333
334 if (requestId == std::numeric_limits<int32_t>::max()) {
335 FI_HILOGE("Request ID exceeds the maximum");
336 requestId = 0;
337 }
338 return requestId++;
339 }
340
OnCoordinationListener(const StreamClient & client,NetPacket & pkt)341 int32_t CooperateClient::OnCoordinationListener(const StreamClient &client, NetPacket &pkt)
342 {
343 CALL_INFO_TRACE;
344 int32_t userData = 0;
345 std::string networkId;
346 int32_t nType = 0;
347 pkt >> userData >> networkId >> nType;
348 if (pkt.ChkRWError()) {
349 FI_HILOGE("Packet read type failed");
350 return RET_ERR;
351 }
352 FI_HILOGI("NetworkId:%{public}s, nType:%{public}d", Utility::Anonymize(networkId).c_str(), nType);
353 OnDevCooperateListener(networkId, CoordinationMessage(nType));
354 return RET_OK;
355 }
356
OnDevCooperateListener(const std::string & networkId,CoordinationMessage msg)357 void CooperateClient::OnDevCooperateListener(const std::string &networkId, CoordinationMessage msg)
358 {
359 CALL_INFO_TRACE;
360 std::lock_guard<std::mutex> guard(mtx_);
361 for (const auto &item : devCooperateListener_) {
362 item->OnCoordinationMessage(networkId, msg);
363 }
364 }
365
OnCoordinationMessage(const StreamClient & client,NetPacket & pkt)366 int32_t CooperateClient::OnCoordinationMessage(const StreamClient &client, NetPacket &pkt)
367 {
368 CALL_INFO_TRACE;
369 int32_t userData = 0;
370 std::string networkId;
371 int32_t nType = 0;
372 int32_t errCode = -1;
373 pkt >> userData >> networkId >> nType >> errCode;
374 if (pkt.ChkRWError()) {
375 FI_HILOGE("Packet read coordination msg failed");
376 return RET_ERR;
377 }
378 #ifdef ENABLE_PERFORMANCE_CHECK
379 FinishTrace(userData, CoordinationMessage(nType));
380 #endif // ENABLE_PERFORMANCE_CHECK
381 FI_HILOGI("NetworkId:%{public}s, nType:%{public}d", Utility::Anonymize(networkId).c_str(), nType);
382 CoordinationMsgInfo msgInfo { .msg = static_cast<CoordinationMessage>(nType), .errCode = errCode };
383 OnCooperateMessageEvent(userData, networkId, msgInfo);
384 return RET_OK;
385 }
386
OnCooperateMessageEvent(int32_t userData,const std::string & networkId,const CoordinationMsgInfo & msgInfo)387 void CooperateClient::OnCooperateMessageEvent(
388 int32_t userData, const std::string &networkId, const CoordinationMsgInfo &msgInfo)
389 {
390 CALL_INFO_TRACE;
391 CHK_PID_AND_TID();
392 std::lock_guard<std::mutex> guard(mtx_);
393 auto iter = devCooperateEvent_.find(userData);
394 if (iter == devCooperateEvent_.end()) {
395 return;
396 }
397 CooperateMessageCallback callback = iter->second.msgCb;
398 CHKPV(callback);
399 callback(networkId, msgInfo);
400 devCooperateEvent_.erase(iter);
401 }
402
OnCoordinationState(const StreamClient & client,NetPacket & pkt)403 int32_t CooperateClient::OnCoordinationState(const StreamClient &client, NetPacket &pkt)
404 {
405 CALL_INFO_TRACE;
406 int32_t userData = 0;
407 bool state = false;
408 int32_t errCode = -1;
409 pkt >> userData >> state >> errCode;
410 if (pkt.ChkRWError()) {
411 FI_HILOGE("Packet read coordination msg failed");
412 return RET_ERR;
413 }
414 FI_HILOGI("State%{public}s", state ? "true" : "false");
415 OnCooperateStateEvent(userData, state);
416 return RET_OK;
417 }
418
OnCooperateStateEvent(int32_t userData,bool state)419 void CooperateClient::OnCooperateStateEvent(int32_t userData, bool state)
420 {
421 CALL_INFO_TRACE;
422 CHK_PID_AND_TID();
423 std::lock_guard<std::mutex> guard(mtx_);
424 auto iter = devCooperateEvent_.find(userData);
425 if (iter == devCooperateEvent_.end()) {
426 return;
427 }
428 CooperateStateCallback event = iter->second.stateCb;
429 CHKPV(event);
430 event(state);
431 devCooperateEvent_.erase(iter);
432 FI_HILOGD("Coordination state event callback, userData:%{public}d, state:(%{public}d)", userData, state);
433 }
434
OnHotAreaListener(const StreamClient & client,NetPacket & pkt)435 int32_t CooperateClient::OnHotAreaListener(const StreamClient &client, NetPacket &pkt)
436 {
437 CALL_DEBUG_ENTER;
438 int32_t positionX = 0;
439 int32_t positionY = 0;
440 int32_t type = 0;
441 bool isEdge = false;
442 pkt >> positionX >> positionY >> type >> isEdge;
443 if (pkt.ChkRWError()) {
444 FI_HILOGE("Packet read type failed");
445 return RET_ERR;
446 }
447 OnDevHotAreaListener(positionX, positionY, HotAreaType(type), isEdge);
448 return RET_OK;
449 }
450
OnMouseLocationListener(const StreamClient & client,NetPacket & pkt)451 int32_t CooperateClient::OnMouseLocationListener(const StreamClient &client, NetPacket &pkt)
452 {
453 CALL_DEBUG_ENTER;
454 std::string networkId;
455 Event event;
456 pkt >> networkId >> event.displayX >> event.displayY >> event.displayWidth >> event.displayHeight;
457 if (pkt.ChkRWError()) {
458 FI_HILOGE("Packet read type failed");
459 return RET_ERR;
460 }
461 OnDevMouseLocationListener(networkId, event);
462 return RET_OK;
463 }
464
OnDevHotAreaListener(int32_t displayX,int32_t displayY,HotAreaType type,bool isEdge)465 void CooperateClient::OnDevHotAreaListener(int32_t displayX, int32_t displayY, HotAreaType type, bool isEdge)
466 {
467 CALL_DEBUG_ENTER;
468 std::lock_guard<std::mutex> guard(mtx_);
469 for (const auto &item : devHotAreaListener_) {
470 item->OnHotAreaMessage(displayX, displayY, type, isEdge);
471 }
472 }
473
OnDevMouseLocationListener(const std::string & networkId,const Event & event)474 void CooperateClient::OnDevMouseLocationListener(const std::string &networkId, const Event &event)
475 {
476 CALL_DEBUG_ENTER;
477 std::lock_guard<std::mutex> guard(mtx_);
478 if (eventListener_.find(networkId) == eventListener_.end()) {
479 FI_HILOGI("No listener for networkId:%{public}s is registered", Utility::Anonymize(networkId).c_str());
480 return;
481 }
482 for (const auto &listener : eventListener_[networkId]) {
483 CHKPC(listener);
484 listener->OnMouseLocationEvent(networkId, event);
485 FI_HILOGD("Trigger listener for networkId:%{public}s,"
486 "displayX:%{public}d, displayY:%{public}d, displayWidth:%{public}d, displayHeight:%{public}d",
487 Utility::Anonymize(networkId).c_str(), event.displayX, event.displayY, event.displayWidth,
488 event.displayHeight);
489 }
490 }
491
492 #ifdef ENABLE_PERFORMANCE_CHECK
GetFirstSuccessIndex()493 int32_t CooperateClient::GetFirstSuccessIndex()
494 {
495 CALL_DEBUG_ENTER;
496 size_t durationLen = performanceInfo_.durationList.size();
497 for (size_t i = 0; i < durationLen; ++i) {
498 if (performanceInfo_.durationList[i] != FAILURE_DURATION) {
499 performanceInfo_.successNum = 1;
500 FI_HILOGI("[PERF] First success index:%{public}zu", i);
501 return static_cast<int32_t>(i);
502 }
503 }
504 return INVALID_INDEX;
505 }
StartTrace(int32_t userData)506 void CooperateClient::StartTrace(int32_t userData)
507 {
508 CALL_DEBUG_ENTER;
509 std::lock_guard guard { performanceLock_ };
510 performanceInfo_.traces_.emplace(userData, std::chrono::steady_clock::now());
511 performanceInfo_.activateNum += 1;
512 FI_HILOGI("[PERF] Start tracing \'%{public}d\'", userData);
513 }
514
FinishTrace(int32_t userData,CoordinationMessage msg)515 void CooperateClient::FinishTrace(int32_t userData, CoordinationMessage msg)
516 {
517 CALL_DEBUG_ENTER;
518 std::lock_guard guard { performanceLock_ };
519 if (msg == CoordinationMessage::ACTIVATE_SUCCESS) {
520 if (auto iter = performanceInfo_.traces_.find(userData); iter != performanceInfo_.traces_.end()) {
521 auto curDuration =
522 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - iter->second)
523 .count();
524 FI_HILOGI("[PERF] Finish tracing \'%{public}d\', elapsed:%{public}lld ms", userData, curDuration);
525 performanceInfo_.traces_.erase(iter);
526 performanceInfo_.durationList.push_back(curDuration);
527 } else {
528 FI_HILOGW("[PERF] FinishTrace with something wrong");
529 }
530 } else if (msg == CoordinationMessage::ACTIVATE_FAIL) {
531 FI_HILOGW("[PERF] Activate coordination failed");
532 performanceInfo_.traces_.erase(userData);
533 performanceInfo_.durationList.push_back(FAILURE_DURATION);
534 }
535 }
536
DumpPerformanceInfo()537 void CooperateClient::DumpPerformanceInfo()
538 {
539 CALL_DEBUG_ENTER;
540 std::lock_guard guard { performanceLock_ };
541 int32_t firstSuccessIndex = GetFirstSuccessIndex();
542 int32_t durationLen = static_cast<int32_t>(performanceInfo_.durationList.size());
543 if (firstSuccessIndex < 0 || firstSuccessIndex >= durationLen) {
544 FI_HILOGE("[PERF] DumpPerformanceInfo failed, invalid first success index");
545 return;
546 }
547 performanceInfo_.failNum = firstSuccessIndex;
548 performanceInfo_.failBeforeSuccess = firstSuccessIndex;
549 performanceInfo_.firstSuccessDuration = performanceInfo_.durationList[firstSuccessIndex];
550 int32_t successDurationSumWithoutFirst { 0 };
551 for (int32_t i = firstSuccessIndex + 1; i < durationLen; i++) {
552 if (performanceInfo_.durationList[i] != FAILURE_DURATION) {
553 successDurationSumWithoutFirst += performanceInfo_.durationList[i];
554 performanceInfo_.minDuration = std::min(performanceInfo_.durationList[i], performanceInfo_.minDuration);
555 performanceInfo_.maxDuration = std::max(performanceInfo_.durationList[i], performanceInfo_.maxDuration);
556 performanceInfo_.successNum += 1;
557 } else {
558 performanceInfo_.failNum += 1;
559 }
560 }
561 int32_t validActivateNum = performanceInfo_.activateNum - performanceInfo_.failBeforeSuccess;
562 if (validActivateNum > 0) {
563 performanceInfo_.successRate =
564 (static_cast<float>(performanceInfo_.successNum) * PERCENTAGE) / validActivateNum;
565 }
566 if (int32_t successNumWithoutFirst = performanceInfo_.successNum - 1; successNumWithoutFirst > 0) {
567 performanceInfo_.averageDuration = successDurationSumWithoutFirst / successNumWithoutFirst;
568 }
569 FI_HILOGI(
570 "[PERF] performanceInfo:"
571 "activateNum:%{public}d successNum:%{public}d failNum:%{public}d successRate:%{public}.2f "
572 "averageDuration:%{public}d ms maxDuration:%{public}d ms minDuration:%{public}d ms failBeforeSucc:%{public}d "
573 "firstSuccessDuration:%{public}d ms",
574 performanceInfo_.activateNum, performanceInfo_.successNum, performanceInfo_.failNum,
575 performanceInfo_.successRate, performanceInfo_.averageDuration, performanceInfo_.maxDuration,
576 performanceInfo_.minDuration, performanceInfo_.failBeforeSuccess, performanceInfo_.firstSuccessDuration);
577 std::string durationStr;
578 for (auto duration : performanceInfo_.durationList) {
579 durationStr += std::to_string(duration) + ", ";
580 }
581 FI_HILOGI("[PERF] Duration:%{public}s", durationStr.c_str());
582 performanceInfo_ = PerformanceInfo();
583 }
584 #endif // ENABLE_PERFORMANCE_CHECK
585 } // namespace DeviceStatus
586 } // namespace Msdp
587 } // namespace OHOS
588