1 /*
2  * Copyright (c) 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 "dfx/dms_continue_time_dumper.h"
17 
18 #include <iomanip>
19 #include <sstream>
20 
21 #include "cJSON.h"
22 #include "datetime_ex.h"
23 
24 #include "adapter/dnetwork_adapter.h"
25 #include "distributed_sched_utils.h"
26 #include "dtbschedmgr_log.h"
27 #include "dtbschedmgr_device_info_storage.h"
28 #include "deviceManager/dms_device_info.h"
29 #include "distributed_device_node_listener.h"
30 
31 namespace OHOS {
32 namespace DistributedSchedule {
33 namespace {
34 const std::string TAG = "DmsContinueTime";
35 const std::string DMSDURATION_STARTTIME = "Continue Start Time: ";
36 const std::string DMSDURATION_ENDTIME = "Continue End Time  : ";
37 const std::string DMSDURATION_TOTAL = "Total Time Cost             : ";
38 const std::string DMSDURATION_SINKTOSOURCERPC = "-- Request Transaction Cost : ";
39 const std::string DMSDURATION_SOURCEDATASAVE = "-- Source Data Save Cost    : ";
40 const std::string DMSDURATION_SOURCETOSINKRPC = "-- Data Transaction Cost    : ";
41 const std::string DMSDURATION_SINKABILITYSTART = "-- Sink Ability Start Cost  : ";
42 constexpr int32_t DMSDURATION_MAXSIZE = 100;
43 constexpr int32_t DMSDURATION_SPACE = 40;
44 constexpr int32_t DMSDURATION_TOTALTIME = 2;
45 constexpr int32_t DMSDURATION_DSTTOSRCRPCTIME = 3;
46 constexpr int32_t DMSDURATION_SAVETIME = 4;
47 constexpr int32_t DMSDURATION_SRCTODSTRPCTIME = 5;
48 constexpr int32_t DMSDURATION_STARTABILITY = 6;
49 constexpr int32_t DMSDURATION_EMPTY_TIME = 0;
50 }
51 
52 IMPLEMENT_SINGLE_INSTANCE(DmsContinueTime);
53 
DmsDuration(const int64_t begin,const int64_t end,const std::string name)54 DmsDuration::DmsDuration(const int64_t begin, const int64_t end, const std::string name)
55 {
56     beginTime_ = begin;
57     endTime_ = end;
58     durationName_ = name;
59 }
60 
SetBeginTime(const int64_t time)61 void DmsDuration::SetBeginTime(const int64_t time)
62 {
63     beginTime_ = time;
64 }
65 
SetEndTime(const int64_t time)66 void DmsDuration::SetEndTime(const int64_t time)
67 {
68     endTime_ = time;
69 }
70 
SetDurationTime(const int64_t time)71 void DmsDuration::SetDurationTime(const int64_t time)
72 {
73     duration_ = time;
74 }
75 
SetStrTime(const std::string name)76 void DmsDuration::SetStrTime(const std::string name)
77 {
78     strTime_ = name;
79 }
80 
SetDurationName(const std::string name)81 void DmsDuration::SetDurationName(const std::string name)
82 {
83     durationName_ = name;
84 }
85 
GetBeginTime()86 int64_t DmsDuration::GetBeginTime()
87 {
88     return beginTime_;
89 }
90 
GetEndTime()91 int64_t DmsDuration::GetEndTime()
92 {
93     return endTime_;
94 }
95 
GetDurationTime()96 int64_t DmsDuration::GetDurationTime()
97 {
98     return duration_;
99 }
100 
GetStrTime()101 std::string DmsDuration::GetStrTime()
102 {
103     return strTime_;
104 }
105 
GetDurationName()106 std::string DmsDuration::GetDurationName()
107 {
108     return durationName_;
109 }
110 
Init()111 void DmsContinueTime::Init()
112 {
113     srcInfo_.bundleName.clear();
114     srcInfo_.abilityName.clear();
115     srcInfo_.netWorkId.clear();
116     srcInfo_.deviceName.clear();
117     dstInfo_.bundleName.clear();
118     dstInfo_.abilityName.clear();
119     dstInfo_.netWorkId.clear();
120     dstInfo_.deviceName.clear();
121     {
122         std::lock_guard<std::mutex> vecLock(infoMutex_);
123         durationInfo_.clear();
124 
125         durationInfo_.push_back(DmsDuration(0, 0, DMSDURATION_STARTTIME));
126         durationInfo_.push_back(DmsDuration(0, 0, DMSDURATION_ENDTIME));
127         durationInfo_.push_back(DmsDuration(0, 0, DMSDURATION_TOTAL));
128         durationInfo_.push_back(DmsDuration(0, 0, DMSDURATION_SINKTOSOURCERPC));
129         durationInfo_.push_back(DmsDuration(0, 0, DMSDURATION_SOURCEDATASAVE));
130         durationInfo_.push_back(DmsDuration(0, 0, DMSDURATION_SOURCETOSINKRPC));
131         durationInfo_.push_back(DmsDuration(0, 0, DMSDURATION_SINKABILITYSTART));
132     }
133 }
134 
SetPull(bool sign)135 void DmsContinueTime::SetPull(bool sign)
136 {
137     isPull_ = sign;
138 }
139 
GetPull()140 bool DmsContinueTime::GetPull()
141 {
142     return isPull_;
143 }
144 
SetSrcBundleName(const std::string bundleName)145 void DmsContinueTime::SetSrcBundleName(const std::string bundleName)
146 {
147     srcInfo_.bundleName = bundleName;
148 }
149 
SetSrcAbilityName(const std::string abilityName)150 void DmsContinueTime::SetSrcAbilityName(const std::string abilityName)
151 {
152     srcInfo_.abilityName = abilityName;
153 }
154 
SetDstBundleName(const std::string bundleName)155 void DmsContinueTime::SetDstBundleName(const std::string bundleName)
156 {
157     dstInfo_.bundleName = bundleName;
158 }
159 
SetDstAbilityName(const std::string abilityName)160 void DmsContinueTime::SetDstAbilityName(const std::string abilityName)
161 {
162     dstInfo_.abilityName = abilityName;
163 }
164 
SetNetWorkId(const std::string srcNetWorkId,const std::string dstNetWorkId)165 void DmsContinueTime::SetNetWorkId(const std::string srcNetWorkId, const std::string dstNetWorkId)
166 {
167     srcInfo_.netWorkId = srcNetWorkId;
168     dstInfo_.netWorkId = dstNetWorkId;
169 }
170 
SetDeviceNamePull()171 void DmsContinueTime::SetDeviceNamePull()
172 {
173     srcInfo_.deviceName = DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceName(srcInfo_.netWorkId);
174 
175     DistributedHardware::DmDeviceInfo dmDeviceInfo;
176     DnetworkAdapter::GetInstance()->GetLocalBasicInfo(dmDeviceInfo);
177     dstInfo_.deviceName = dmDeviceInfo.deviceName;
178 }
179 
SetDeviceNamePush()180 void DmsContinueTime::SetDeviceNamePush()
181 {
182     dstInfo_.deviceName = DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceName(dstInfo_.netWorkId);
183 
184     DistributedHardware::DmDeviceInfo dmDeviceInfo;
185     DnetworkAdapter::GetInstance()->GetLocalBasicInfo(dmDeviceInfo);
186     srcInfo_.deviceName = dmDeviceInfo.deviceName;
187 }
188 
GetDstInfo()189 DmsDumperInfo DmsContinueTime::GetDstInfo()
190 {
191     return dstInfo_;
192 }
193 
SetDurationBegin(const int32_t idx,const int64_t time)194 void DmsContinueTime::SetDurationBegin(const int32_t idx, const int64_t time)
195 {
196     std::lock_guard<std::mutex> vecLock(infoMutex_);
197     if (durationInfo_.empty() || durationInfo_.size() <= static_cast<size_t>(idx)) {
198         return;
199     }
200     durationInfo_[idx].SetBeginTime(time);
201 }
202 
SetDurationEnd(const int32_t idx,const int64_t time)203 void DmsContinueTime::SetDurationEnd(const int32_t idx, const int64_t time)
204 {
205     std::lock_guard<std::mutex> vecLock(infoMutex_);
206     if (durationInfo_.empty() || durationInfo_.size() <= static_cast<size_t>(idx)) {
207         return;
208     }
209     durationInfo_[idx].SetEndTime(time);
210 }
211 
SetDurationStrTime(const int32_t idx,const std::string info)212 void DmsContinueTime::SetDurationStrTime(const int32_t idx, const std::string info)
213 {
214     std::lock_guard<std::mutex> vecLock(infoMutex_);
215     if (durationInfo_.empty() || durationInfo_.size() <= static_cast<size_t>(idx)) {
216         return;
217     }
218     durationInfo_[idx].SetStrTime(info);
219 }
220 
SetSaveDataDurationBegin(const int64_t time)221 void DmsContinueTime::SetSaveDataDurationBegin(const int64_t time)
222 {
223     saveDataDuration_.SetBeginTime(time);
224 }
225 
SetSaveDataDurationEnd(const int64_t time)226 void DmsContinueTime::SetSaveDataDurationEnd(const int64_t time)
227 {
228     saveDataDuration_.SetEndTime(time);
229 }
230 
GetSaveDataDuration()231 DmsDuration DmsContinueTime::GetSaveDataDuration()
232 {
233     return saveDataDuration_;
234 }
235 
WriteDurationInfo(DmsDuration duration)236 std::string DmsContinueTime::WriteDurationInfo(DmsDuration duration)
237 {
238     cJSON* durationInfo = cJSON_CreateObject();
239     if (durationInfo == nullptr) {
240         HILOGW("Create cJSON Object failed!");
241         return "";
242     }
243     cJSON_AddNumberToObject(durationInfo, "beginTime", duration.GetBeginTime());
244     cJSON_AddNumberToObject(durationInfo, "endTime", duration.GetEndTime());
245     char* cjson_str = cJSON_PrintUnformatted(durationInfo);
246     std::string message(cjson_str);
247     if (message.empty()) {
248         HILOGW("Write Info failed!");
249     }
250     cJSON_Delete(durationInfo);
251     cJSON_free(cjson_str);
252     return message;
253 }
254 
ReadDurationInfo(const char * info)255 void DmsContinueTime::ReadDurationInfo(const char* info)
256 {
257     cJSON* durationInfo = cJSON_Parse(info);
258     if (durationInfo == nullptr) {
259         HILOGW("Accept cJSON Object failed!");
260         return;
261     }
262     cJSON* beginTimeItem = cJSON_GetObjectItem(durationInfo, "beginTime");
263     if (beginTimeItem == nullptr || !cJSON_IsNumber(beginTimeItem)) {
264         cJSON_Delete(durationInfo);
265         return;
266     }
267     int64_t beginTime = beginTimeItem->valueint;
268     cJSON* endTimeItem = cJSON_GetObjectItem(durationInfo, "endTime");
269     if (endTimeItem == nullptr || !cJSON_IsNumber(endTimeItem)) {
270         cJSON_Delete(durationInfo);
271         return;
272     }
273     int64_t endTime = endTimeItem->valueint;
274     saveDataDuration_.SetBeginTime(beginTime);
275     saveDataDuration_.SetEndTime(endTime);
276     cJSON_Delete(durationInfo);
277 }
278 
WriteDstInfo(const std::string bundleName,const std::string abilityName)279 std::string DmsContinueTime::WriteDstInfo(const std::string bundleName, const std::string abilityName)
280 {
281     cJSON* info = cJSON_CreateObject();
282     if (info == nullptr) {
283         HILOGW("Create cJSON Object failed!");
284         return "";
285     }
286     cJSON_AddStringToObject(info, "DstBundleName", bundleName.c_str());
287     cJSON_AddStringToObject(info, "DstAbilityName", abilityName.c_str());
288     char* cjson_str = cJSON_PrintUnformatted(info);
289     std::string message(cjson_str);
290     if (message.empty()) {
291         HILOGW("Write info failed!");
292     }
293     cJSON_Delete(info);
294     cJSON_free(cjson_str);
295     return message;
296 }
297 
ReadDstInfo(const char * info)298 void DmsContinueTime::ReadDstInfo(const char* info)
299 {
300     cJSON* dstInfo = cJSON_Parse(info);
301     if (dstInfo == nullptr) {
302         HILOGW("Accept cJSON Object failed!");
303         return;
304     }
305     cJSON* bundleNameItem = cJSON_GetObjectItem(dstInfo, "DstBundleName");
306     if (bundleNameItem == nullptr || !cJSON_IsString(bundleNameItem) || (bundleNameItem->valuestring == nullptr)) {
307         cJSON_Delete(dstInfo);
308         return;
309     }
310     std::string bundleName = bundleNameItem->valuestring;
311     cJSON* abilityNameItem = cJSON_GetObjectItem(dstInfo, "DstAbilityName");
312     if (abilityNameItem == nullptr || !cJSON_IsString(abilityNameItem) || (abilityNameItem->valuestring == nullptr)) {
313         cJSON_Delete(dstInfo);
314         return;
315     }
316     std::string abilityName = abilityNameItem->valuestring;
317     dstInfo_.bundleName = bundleName;
318     dstInfo_.abilityName = abilityName;
319     cJSON_Delete(dstInfo);
320 }
321 
GetCurrentTime()322 std::string DmsContinueTime::GetCurrentTime()
323 {
324     std::chrono::system_clock::time_point time = std::chrono::system_clock::now();
325     std::time_t time_c = std::chrono::system_clock::to_time_t(time);
326     std::tm* time_tm = std::localtime(&time_c);
327     std::stringstream timeStr;
328     timeStr << std::put_time(time_tm, "%Y/%m/%d %H:%M:%S");
329     return timeStr.str();
330 }
331 
DealDurationPull()332 void DmsContinueTime::DealDurationPull()
333 {
334     std::lock_guard<std::mutex> vecLock(infoMutex_);
335     if (durationInfo_.size() <= DMSDURATION_STARTABILITY) {
336         HILOGW("durationInfo_ does not have enough space");
337         return;
338     }
339 
340     durationInfo_[DMSDURATION_SAVETIME].SetBeginTime(saveDataDuration_.GetBeginTime());
341     durationInfo_[DMSDURATION_SAVETIME].SetEndTime(saveDataDuration_.GetEndTime());
342 
343     for (auto& duration : durationInfo_) {
344         if (duration.GetStrTime().empty() && duration.GetBeginTime() != 0 && duration.GetEndTime() != 0) {
345             duration.SetDurationTime(duration.GetEndTime() - duration.GetBeginTime());
346             duration.SetStrTime(std::to_string(duration.GetDurationTime()) += "ms");
347         }
348     }
349     durationInfo_[DMSDURATION_SRCTODSTRPCTIME].SetDurationTime(
350         durationInfo_[DMSDURATION_TOTALTIME].GetDurationTime() -
351         durationInfo_[DMSDURATION_DSTTOSRCRPCTIME].GetDurationTime() -
352         durationInfo_[DMSDURATION_SAVETIME].GetDurationTime() -
353         durationInfo_[DMSDURATION_STARTABILITY].GetDurationTime());
354     durationInfo_[DMSDURATION_SRCTODSTRPCTIME].SetStrTime(
355         std::to_string(durationInfo_[DMSDURATION_SRCTODSTRPCTIME].GetDurationTime()) += "ms");
356 }
357 
DealDurationPush()358 void DmsContinueTime::DealDurationPush()
359 {
360     std::lock_guard<std::mutex> vecLock(infoMutex_);
361     if (durationInfo_.size() <= DMSDURATION_STARTABILITY) {
362         HILOGW("durationInfo_ does not have enough space");
363         return;
364     }
365 
366     durationInfo_[DMSDURATION_SAVETIME].SetBeginTime(saveDataDuration_.GetBeginTime());
367     durationInfo_[DMSDURATION_SAVETIME].SetEndTime(saveDataDuration_.GetEndTime());
368 
369     for (auto& duration : durationInfo_) {
370         if (duration.GetStrTime().empty() && duration.GetBeginTime() != 0 && duration.GetEndTime() != 0) {
371             duration.SetDurationTime(duration.GetEndTime() - duration.GetBeginTime());
372             duration.SetStrTime(std::to_string(duration.GetDurationTime()) += "ms");
373         }
374     }
375     durationInfo_[DMSDURATION_STARTABILITY].SetDurationTime(
376         durationInfo_[DMSDURATION_STARTABILITY].GetDurationTime() -
377         durationInfo_[DMSDURATION_SRCTODSTRPCTIME].GetDurationTime());
378     durationInfo_[DMSDURATION_STARTABILITY].SetStrTime(
379         std::to_string(durationInfo_[DMSDURATION_STARTABILITY].GetDurationTime()) += "ms");
380 }
381 
AppendInfo()382 void DmsContinueTime::AppendInfo()
383 {
384     if (isPull_) {
385         SetDeviceNamePull();
386         DealDurationPull();
387         appendInfo_.append("PULL\n");
388     } else {
389         SetDeviceNamePush();
390         DealDurationPush();
391         appendInfo_.append("PUSH\n");
392     }
393 
394     std::stringstream str;
395     str << "== SOURCE ==\n"
396         << "Network Id  : " << std::setw(DMSDURATION_SPACE) << std::left
397         << GetAnonymStr(srcInfo_.netWorkId.c_str())
398         << "Device Name  : " << srcInfo_.deviceName << "\n"
399         << "Bundle Name : " << std::setw(DMSDURATION_SPACE) << std::left
400         << srcInfo_.bundleName
401         << "Ability Name : " << srcInfo_.abilityName << "\n"
402         << "== SINK ==\n"
403         << "Network Id  : " << std::setw(DMSDURATION_SPACE) << std::left
404         << GetAnonymStr(dstInfo_.netWorkId.c_str())
405         << "Device Name  : " << dstInfo_.deviceName << "\n"
406         << "Bundle Name : " << std::setw(DMSDURATION_SPACE) << std::left
407         << dstInfo_.bundleName
408         << "Ability Name : " << dstInfo_.abilityName << "\n";
409     appendInfo_.append(str.str());
410     appendInfo_.append("------------------------------------------------------------------------------------\n");
411 
412     {
413         std::lock_guard<std::mutex> vecLock(infoMutex_);
414         for (auto duration : durationInfo_) {
415             appendInfo_.append(duration.GetDurationName().c_str());
416             appendInfo_.append(duration.GetStrTime().c_str());
417             appendInfo_.append("\n");
418         }
419 
420         if (timeInfoList_.size() >= DMSDURATION_MAXSIZE) {
421             timeInfoList_.pop_front();
422         }
423         timeInfoList_.push_back(appendInfo_);
424         appendInfo_.clear();
425         durationInfo_.clear();
426     }
427 }
428 
ShowInfo(std::string & result)429 void DmsContinueTime::ShowInfo(std::string& result)
430 {
431     int32_t nIdx = 1;
432     for (const auto& info : timeInfoList_) {
433         result.append("[" + std::to_string(nIdx) + "]\n");
434         result.append("------------------------------------------------------------------------------------\n");
435         result.append(info.c_str());
436         result.append("------------------------------------------------------------------------------------\n");
437         nIdx++;
438     }
439 }
440 
GetTotalTime()441 int64_t DmsContinueTime::GetTotalTime()
442 {
443     std::lock_guard<std::mutex> vecLock(infoMutex_);
444     HILOGD("GetTotalTime start, durationInfo_.size is %{public}zu", durationInfo_.size());
445     if (durationInfo_.empty() || durationInfo_.size() <= DMSDURATION_TOTALTIME) {
446         HILOGE("totalTime is not exist.");
447         return DMSDURATION_EMPTY_TIME;
448     }
449     return durationInfo_[DMSDURATION_TOTALTIME].GetEndTime() - durationInfo_[DMSDURATION_TOTALTIME].GetBeginTime();
450 }
451 }
452 }