• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "report.h"
17 
18 #include <algorithm>
19 #include <dirent.h>
20 #include <fstream>
21 #include <iostream>
22 #include <sstream>
23 #include <sys/inotify.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 
27 #include "ability_manager_client.h"
28 #include "element_name.h"
29 #include "exception_manager.h"
30 #include "filter_category.h"
31 #include "format_csv.h"
32 #include "format_json.h"
33 #include "statistics_ability.h"
34 #include "statistics_componment.h"
35 #include "statistics_event.h"
36 #include "statistics_exception.h"
37 #include "string_ex.h"
38 #include "wukong_define.h"
39 #include "wukong_util.h"
40 
41 namespace OHOS {
42 namespace WuKong {
43 namespace {
44 const uint32_t SEGMENT_STATISTICS_LENGTH = 10;
45 std::string crashDir = "/data/log/faultlog/faultlogger/";
ListenCrashDir()46 void ListenCrashDir()
47 {
48     int fd;
49     int wd;
50     ssize_t readLenght;
51     char buf[BUFSIZ];
52     char* bufPtr = nullptr;
53     struct inotify_event *event;
54     fd = inotify_init();
55     INFO_LOG("init notify");
56     if (fd < 0) {
57         return;
58     }
59     wd = inotify_add_watch(fd, "/data/log/faultlog/faultlogger/", IN_CLOSE_WRITE);
60     INFO_LOG("add_watch");
61     if (wd < 0) {
62         ERROR_LOG("inotify_add_watch /data/log/faultlog/faultlogger/ failed");
63         return;
64     }
65     buf[sizeof(buf) - 1] = 0;
66     std::string destDir = Report::GetInstance()->GetReportExceptionDir();
67     while ((readLenght = read(fd, buf, sizeof(buf) - 1)) > 0) {
68         uint32_t len = static_cast<uint32_t>(readLenght);
69         uint32_t nread = 0;
70         while (len > 0) {
71             bufPtr = &buf[nread];
72             void* middleType =  static_cast<void *>(bufPtr);
73             event = static_cast<struct inotify_event *>(middleType);
74             if ((event->mask & IN_CLOSE_WRITE) && (event->len > 0)) {
75                 DEBUG_LOG_STR("event->mask{%x}", event->mask);
76                 std::string targetFile(event->name);
77                 WuKongUtil::GetInstance()->CopyFile(targetFile, crashDir, destDir);
78                 DEBUG_LOG_STR("%s --- IN_CLOSE_WRITE\n", event->name);
79                 Report::GetInstance()->ExceptionRecord(targetFile);
80             }
81             nread = nread + sizeof(struct inotify_event) + event->len;
82             len = len - sizeof(struct inotify_event) - event->len;
83         }
84     }
85     INFO_LOG("exit thread");
86     return;
87 }
88 
StartCrashDirListen()89 void StartCrashDirListen()
90 {
91     std::thread listenerThread(&ListenCrashDir);
92     INFO_LOG("create listener thread");
93     listenerThread.detach();
94     INFO_LOG("thread detach");
95 }
96 }  // namespace
97 using namespace OHOS::AAFwk;
Report()98 Report::Report()
99 {
100     EnvInit();
101     DataSetInit();
102 }
103 
EnvInit()104 void Report::EnvInit()
105 {
106     const std::string DEFAULT_DIR = "/data/local/tmp/wukong/report/";
107     startRunTime_ = WuKongUtil::GetInstance()->GetStartRunTime();
108     // Get a screenshot within the previous timestamp of the current timestamp
109     DIR *dirp = nullptr;
110     dirp = opendir(DEFAULT_DIR.c_str());
111     std::string maxValue = "";
112     std::string targetTimeDir;
113     // setting filename
114     currentTestDir_ = WuKongUtil::GetInstance()->GetCurrentTestDir();
115     INFO_LOG_STR("Report currentTestDir: (%s)", currentTestDir_.c_str());
116     // setting filename
117     reportCsvFileName_ = currentTestDir_ + "wukong_report.csv";
118     reportJsonFileName_ = currentTestDir_ + "data.js";
119     reportFocusInputFileName_ = currentTestDir_ + "focus_report";
120 
121     INFO_LOG_STR("Report CSV: (%s)", reportCsvFileName_.c_str());
122     INFO_LOG_STR("Report JSON: (%s)", reportJsonFileName_.c_str());
123 
124     reportExceptionDir_ = currentTestDir_ + "exception/";
125     INFO_LOG_STR("Report exception dir: (%s)", reportExceptionDir_.c_str());
126     int dirExist = access(reportExceptionDir_.c_str(), F_OK);
127     if (dirExist != 0) {
128         int dirStatus = mkdir((reportExceptionDir_).c_str(), 0777);
129         if (dirStatus == -1) {
130             ERROR_LOG("exception dir create fail");
131         }
132     }
133     StartCrashDirListen();
134     // register crash catcher
135     ExceptionManager::GetInstance()->StartCatching();
136     if (dirp == nullptr) {
137         ERROR_LOG_STR("dir{%s} opendir error", DEFAULT_DIR.c_str());
138         return;
139     }
140     while (dirp != nullptr) {
141         struct dirent *dp;
142         if ((dp = readdir(dirp)) == NULL) {
143             break;
144         }
145         std::string currentStringName(dp->d_name);
146         if (currentStringName != startRunTime_) {
147             if (currentStringName > maxValue) {
148                 maxValue = currentStringName;
149                 targetTimeDir = currentStringName;
150             }
151         }
152     }
153     (void)closedir(dirp);
154     // Delete the screenshot under the timestamp
155     std::string targetDir_ = DEFAULT_DIR + targetTimeDir +"/screenshot/";
156     WuKongUtil::GetInstance()->DeleteFile(targetDir_);
157 }
158 
DataSetInit()159 void Report::DataSetInit()
160 {
161     std::shared_ptr<Filter> categoryFilter = std::make_shared<FilterCategory>();
162     eventDataSet_->SetFilterStragety(categoryFilter);
163     eventDataSet_->SetFilterType("event");
164     std::shared_ptr<Statistics> eventSatistics = std::make_shared<StatisticsEvent>();
165     eventDataSet_->SetStatisticsStragety(eventSatistics);
166 
167     // set componment filter,statistics,format
168     componmentDataSet_->SetFilterStragety(categoryFilter);
169     componmentDataSet_->SetFilterType("componment");
170     std::shared_ptr<Statistics> componmentSatistics = std::make_shared<StatisticsComponment>();
171     componmentDataSet_->SetStatisticsStragety(componmentSatistics);
172 
173     // set ability filter,statistics,format
174     abilityDataSet_->SetFilterStragety(categoryFilter);
175     abilityDataSet_->SetFilterType("abilityName");
176     std::shared_ptr<Statistics> abilitySatistics = std::make_shared<StatisticsAbility>();
177     abilityDataSet_->SetStatisticsStragety(abilitySatistics);
178 
179     // set exception filter,statistics,format
180     exceptionDataSet_->SetFilterStragety(categoryFilter);
181     exceptionDataSet_->SetFilterType("exception");
182     std::shared_ptr<Statistics> exceptionSatistics = std::make_shared<StatisticsException>();
183     exceptionDataSet_->SetStatisticsStragety(exceptionSatistics);
184 }
185 
SyncInputInfo(std::shared_ptr<InputedMsgObject> inputedMsgObject)186 void Report::SyncInputInfo(std::shared_ptr<InputedMsgObject> inputedMsgObject)
187 {
188     TRACK_LOG_STD();
189     std::shared_ptr<AbilityManagerClient> abilityManagerClient = AbilityManagerClient::GetInstance();
190     OHOS::AppExecFwk::ElementName elementName = abilityManagerClient->GetTopAbility();
191     std::map<std::string, std::string> data;
192     data["bundleName"] = elementName.GetBundleName();
193     data["abilityName"] = elementName.GetAbilityName();
194     DEBUG_LOG_STR("bundleName{%s} abilityName{%s} ", data["bundleName"].c_str(), data["abilityName"].c_str());
195     SplitInputMode(inputedMsgObject, data);
196 
197     // first appswitch abandon
198     std::map<std::string, std::string>::iterator it = data.find("event");
199     if (it != data.end() && (data["event"] == "appswitch") && (isFirstAppSwitch_ == false)) {
200         DEBUG_LOG("first appswitch abandon");
201         isFirstAppSwitch_ = true;
202         return;
203     }
204     // record app used to control data display
205     std::vector<std::string>::iterator bundleIter = std::find(bundles_.begin(), bundles_.end(), data["bundleName"]);
206     if (bundleIter == bundles_.end()) {
207         DEBUG_LOG_STR("push apps item{%s}", data["bundleName"].c_str());
208         bundles_.push_back(data["bundleName"]);
209     }
210     // send `k => v` to filter
211     eventDataSet_->FilterData(data);
212     componmentDataSet_->FilterData(data);
213     abilityDataSet_->FilterData(data);
214     taskCount_++;
215     DEBUG_LOG_STR("taskCount{%d}", taskCount_);
216     if (is_focus_) {
217         GroupFocusDataAndRecord(inputedMsgObject, data);
218     }
219     // statistics and storage every 10 data
220     if ((taskCount_ % SEGMENT_STATISTICS_LENGTH) == 0) {
221         HilogFileRecord();
222         SegmentedWriteCSV();
223         SegmentedWriteJson();
224         if (is_focus_) {
225             SegmentedWriteForFocusInput();
226         }
227     }
228     TRACK_LOG_END();
229 }
230 
SplitInputMode(std::shared_ptr<InputedMsgObject> & inputedMsgObject,std::map<std::string,std::string> & data)231 void Report::SplitInputMode(std::shared_ptr<InputedMsgObject> &inputedMsgObject,
232     std::map<std::string, std::string> &data)
233 {
234     inputedMode inputMode = inputedMsgObject->GetInputedMode();
235     switch (inputMode) {
236         case multimodeInput: {
237             auto inputMutlMsgPtr = std::static_pointer_cast<MultimodeInputMsg>(inputedMsgObject);
238             data["event"] = inputMutlMsgPtr->GetInputType();
239             DEBUG_LOG_STR("eventType{%s}", data["event"].c_str());
240             break;
241         }
242 
243         case componmentInput: {
244             auto inputCompMsgPtr = std::static_pointer_cast<ComponmentInputMsg>(inputedMsgObject);
245             ComponmentInfoArrange(data["bundleName"], inputCompMsgPtr, data);
246             DEBUG_LOG("componmentType map");
247             break;
248         }
249         default:
250             break;
251     }
252 }
253 
GroupFocusDataAndRecord(std::shared_ptr<InputedMsgObject> & inputedMsgObject,std::map<std::string,std::string> & data)254 void Report::GroupFocusDataAndRecord(std::shared_ptr<InputedMsgObject> &inputedMsgObject,
255     std::map<std::string, std::string> &data)
256 {
257     TRACK_LOG_STD();
258     inputedMode inputMode = inputedMsgObject->GetInputedMode();
259     if (inputMode != componmentInput) {
260         return;
261     }
262     auto inputCompMsgPtr = std::static_pointer_cast<ComponmentInputMsg>(inputedMsgObject);
263     std::string item = "";
264     time_t currentTime = time(0);
265     std::string timeStr = "";
266     if (currentTime > 0) {
267         timeStr = std::to_string(currentTime);
268     }
269     item += std::to_string(taskCount_) + ",";
270     item += timeStr + ",";
271     item += data["abilityName"] + ",";
272     item += inputCompMsgPtr->pagePath_ + ",";
273     item += inputCompMsgPtr->componmentType_ + ",";
274     item += std::to_string(inputCompMsgPtr->startX_) + ",";
275     item += std::to_string(inputCompMsgPtr->startY_) + ",";
276     item += std::to_string(inputCompMsgPtr->endX_) + ",";
277     item += std::to_string(inputCompMsgPtr->endY_) + ",";
278     item += inputCompMsgPtr->content_ + ",";
279     item += std::to_string(inputCompMsgPtr->pssTotal_);
280     focus_input_vec_.push_back(item);
281     TRACK_LOG_END();
282 }
283 
~Report()284 Report::~Report()
285 {
286 }
287 
SegmentedWriteCSV()288 void Report::SegmentedWriteCSV()
289 {
290     TRACK_LOG_STD();
291     // csv report format
292     if (reportCsvFileName_.empty()) {
293         return;
294     }
295     std::shared_ptr<FormatCSV> formatCSV = std::make_shared<FormatCSV>();
296     eventDataSet_->SetFormatStragety(formatCSV);
297     componmentDataSet_->SetFormatStragety(formatCSV);
298     abilityDataSet_->SetFormatStragety(formatCSV);
299     exceptionDataSet_->SetFormatStragety(formatCSV);
300     std::stringstream modules;
301     modules << "module, Base Info" << std::endl;
302     modules << "name, base" << std::endl;
303     modules << "detail, info" << std::endl;
304     modules << "name, base, detail, info" << std::endl;
305     modules << "task status, success" << std::endl;
306     modules << "task time  , " << time(0) - startTime_ << std::endl;
307     if (!seed_.empty()) {
308         modules << "seed , " << seed_ << std::endl;
309     }
310     modules << "task count , " << taskCount_ << std::endl;
311     DEBUG_LOG("start event statistics");
312     eventDataSet_->StatisticsData();
313     DEBUG_LOG("end event statistics");
314     DEBUG_LOG("start componment statistics");
315     componmentDataSet_->StatisticsData();
316     DEBUG_LOG("end componment statistics");
317     std::string moduleInput;
318     modules << "module, Input Message Statistics" << std::endl;
319     modules << "name, all";
320     // show all app and detail
321     for (auto bundleIter : bundles_) {
322         modules << ", " << bundleIter;
323     }
324     modules << std::endl;
325     modules << "detail, event, componment" << std::endl;
326     eventDataSet_->FormatData("all", moduleInput);
327     componmentDataSet_->FormatData("all", moduleInput);
328     // loop app show name-type statistics content
329     for (auto bundleIter : bundles_) {
330         eventDataSet_->FormatData(bundleIter, moduleInput);
331         componmentDataSet_->FormatData(bundleIter, moduleInput);
332     }
333     modules << moduleInput;
334     modules << "module, ability Statistics" << std::endl;
335     modules << "name, all" << std::endl;
336     modules << "detail, ability" << std::endl;
337     moduleInput = "";
338     abilityDataSet_->StatisticsData();
339     abilityDataSet_->FormatData("all", moduleInput);
340     modules << moduleInput;
341 
342     std::unique_lock<std::mutex> locker(crashMtx_);
343     modules << "module, Exception Message Statistics" << std::endl;
344     modules << "name, exception" << std::endl;
345     modules << "detail, statistics" << std::endl;
346     moduleInput = "";
347     exceptionDataSet_->StatisticsData();
348     exceptionDataSet_->FormatData("exception", moduleInput);
349     modules << moduleInput;
350     locker.unlock();
351     std::string csvContent = modules.str();
352     std::fstream csvFileStream(reportCsvFileName_, std::ios::out | std::ios::trunc);
353     csvFileStream << csvContent << std::endl;
354     csvFileStream.close();
355     TRACK_LOG_END();
356 }
357 
SegmentedWriteJson()358 void Report::SegmentedWriteJson()
359 {
360     TRACK_LOG_STD();
361     DEBUG_LOG("SegmentedWriteJson start");
362     // csv report format
363     if (reportCsvFileName_.empty()) {
364         return;
365     }
366     std::shared_ptr<FormatJSON> formatJSON = std::make_shared<FormatJSON>();
367     eventDataSet_->SetFormatStragety(formatJSON);
368     componmentDataSet_->SetFormatStragety(formatJSON);
369     abilityDataSet_->SetFormatStragety(formatJSON);
370     exceptionDataSet_->SetFormatStragety(formatJSON);
371     std::stringstream modules;
372     std::string moduleInput;
373     modules << "var reportJson = {" << std::endl;
374     modules << "base: [" << std::endl;
375     modules << "{ item: \"task status\", detail: \" success \"}," << std::endl;
376     modules << "{ item: \"task time\", detail: \" " << time(0) - startTime_ << "s\"}," << std::endl;
377     modules << "{ item: \"task count\", detail: \" " << taskCount_ << "\"}," << std::endl;
378     if (!seed_.empty()) {
379         modules << "{ item: \"seed\", detail: \" " << seed_ << "\"}," << std::endl;
380     }
381     modules << "]," << std::endl;
382     modules << "detailApps:{" << std::endl;
383     modules << "names:[ \"all\"";
384     // show all app and detail
385     for (auto bundleIter : bundles_) {
386         modules << ", \"" << bundleIter << " \"";
387     }
388     modules << "]," << std::endl;
389     modules << "details: [" << std::endl;
390     modules << "{" << std::endl;
391     modules << "eventStatistics:" << std::endl;
392     eventDataSet_->FormatData("all", moduleInput);
393     modules << moduleInput;
394     modules << "controlStatistics:";
395     componmentDataSet_->FormatData("all", moduleInput);
396     modules << moduleInput;
397     modules << "},";
398     // loop app show name-type statistics content
399     for (auto bundleIter : bundles_) {
400         modules << "{" << std::endl;
401         modules << "eventStatistics:";
402         eventDataSet_->FormatData(bundleIter, moduleInput);
403         modules << moduleInput;
404         modules << "controlStatistics:";
405         componmentDataSet_->FormatData(bundleIter, moduleInput);
406         modules << moduleInput;
407         modules << "},";
408     }
409     modules << "]" << std::endl;
410     modules << "}," << std::endl;
411     modules << "abilityStatistics:";
412     abilityDataSet_->FormatData("all", moduleInput);
413     modules << moduleInput;
414     modules << "detailException: {" << std::endl;
415     modules << "names: [\"exception statistics\", \"cpp crash statistics\", \"js crash statistics\"]," << std::endl;
416     modules << "details: [" << std::endl;
417     modules << "{" << std::endl;
418     modules << "exception_statistics: {" << std::endl;
419     modules << "header: [\"Type\", \"Times\", \"Proportion\"]," << std::endl;
420     modules << "content: " << std::endl;
421     exceptionDataSet_->FormatData("exception", moduleInput);
422     modules << moduleInput;
423     modules << "}," << std::endl;
424     modules << "}," << std::endl;
425     modules << "]" << std::endl;
426     modules << "}," << std::endl;
427     unsigned int index = 0;
428     modules << "screens:[" << std::endl;
429     for (auto srceen : screenPaths_) {
430         modules << "{index:\"" << index << "\","
431                 << "path:\"" << srceen << "\"}," << std::endl;
432         index++;
433     }
434     modules << "]," << std::endl;
435     modules << "};" << std::endl;
436     std::string jsonContent = modules.str();
437     std::fstream jsonFileStream(reportJsonFileName_, std::ios::out | std::ios::trunc);
438     jsonFileStream << jsonContent << std::endl;
439     jsonFileStream.close();
440     DEBUG_LOG("SegmentedWriteJson end");
441     TRACK_LOG_END();
442 }
443 
SegmentedWriteForFocusInput()444 void Report::SegmentedWriteForFocusInput()
445 {
446     TRACK_LOG_STD();
447     DEBUG_LOG("SegmentedWriteForFocusInput start");
448     // csv report format
449     if (reportFocusInputFileName_.empty()) {
450         return;
451     }
452 
453     std::stringstream modules;
454     for (size_t i = 0; i < focus_input_vec_.size(); ++i) {
455         modules << focus_input_vec_[i];
456         if (i < focus_input_vec_.size() - 1) {
457             modules << std::endl;
458         }
459     }
460     focus_input_vec_.clear();
461     std::string jsonContent = modules.str();
462     std::fstream jsonFileStream(reportFocusInputFileName_, std::ios::app);
463     jsonFileStream << jsonContent << std::endl;
464     jsonFileStream.close();
465     DEBUG_LOG("SegmentedWriteForFocusInput end");
466     TRACK_LOG_END();
467 }
468 
HilogFileRecord()469 void Report::HilogFileRecord()
470 {
471     struct dirent *dp;
472     DIR *dirpHilog = nullptr;
473     std::shared_ptr<WuKongUtil> utilPtr = WuKongUtil::GetInstance();
474     dirpHilog = opendir(hilogDirs_.c_str());
475     if (dirpHilog == nullptr) {
476         ERROR_LOG_STR("dir{%s} opendir error", hilogDirs_.c_str());
477         return;
478     }
479     while ((dp = readdir(dirpHilog)) != NULL) {
480         std::string targetFile(dp->d_name);
481         if ((strcmp(dp->d_name, ".") != 0) && (strcmp(dp->d_name, "..") != 0)) {
482             std::vector<std::string>::iterator iterDir = find(hilogFiles_.begin(), hilogFiles_.end(), targetFile);
483             if (iterDir == hilogFiles_.end()) {
484                 DEBUG_LOG("hilog copy action");
485                 utilPtr->CopyFile(targetFile, hilogDirs_, reportExceptionDir_);
486                 hilogFiles_.push_back(targetFile);
487             }
488         }
489     }
490     if (dirpHilog != nullptr) {
491         (void)closedir(dirpHilog);
492     }
493 }
494 
ExceptionRecord(const std::string & exceptionFilename)495 void Report::ExceptionRecord(const std::string &exceptionFilename)
496 {
497     std::unique_lock<std::mutex> locker(crashMtx_);
498     std::map<std::string, std::string> data;
499     std::string exceptionType;
500     if (exceptionFilename.find("cppcrash") != std::string::npos) {
501         exceptionType = "cppcrash";
502     }
503 
504     if (exceptionFilename.find("appfreeze") != std::string::npos) {
505         exceptionType = "appfreeze";
506     }
507 
508     if (exceptionFilename.find("jscrash") != std::string::npos) {
509         exceptionType = "jscrash";
510     }
511 
512     if (exceptionFilename.find("serviceblock") != std::string::npos) {
513         exceptionType = "serviceblock";
514     }
515 
516     data["exception"] = exceptionType;
517     exceptionDataSet_->FilterData(data);
518 }
519 
Finish()520 void Report::Finish()
521 {
522     SegmentedWriteCSV();
523     SegmentedWriteJson();
524     if (is_focus_) {
525         SegmentedWriteForFocusInput();
526     }
527     ExceptionManager::GetInstance()->StopCatching();
528 }
529 
SetSeed(std::string seed)530 void Report::SetSeed(std::string seed)
531 {
532     seed_ = seed;
533 }
534 
ComponmentInfoArrange(const std::string & bundle,std::shared_ptr<ComponmentInputMsg> inputCompMsgPtr,std::map<std::string,std::string> & data)535 void Report::ComponmentInfoArrange(const std::string &bundle, std::shared_ptr<ComponmentInputMsg> inputCompMsgPtr,
536                                    std::map<std::string, std::string> &data)
537 {
538     std::map<std::string, componmentRecord>::iterator bundleComponmentRecordIter;
539     componmentRecord componmentRecord;
540     bundleComponmentRecordIter = bundleComponmentRecord_.find(bundle);
541     if (bundleComponmentRecordIter != bundleComponmentRecord_.end()) {
542         componmentRecord = bundleComponmentRecordIter->second;
543     }
544     componmentRecord.pageIdComponments[inputCompMsgPtr->pageId_] = inputCompMsgPtr->pageComponments;
545     std::map<std::string, uint32_t>::iterator componmentTypeCountIter;
546     uint32_t componmentTypeInputedCount = 0;
547     uint32_t componmentTypeTotal = 0;
548     componmentTypeCountIter = componmentRecord.componmentTypeCount.find(inputCompMsgPtr->componmentType_);
549     if (componmentTypeCountIter != componmentRecord.componmentTypeCount.end()) {
550         componmentTypeInputedCount = componmentTypeCountIter->second;
551     }
552     componmentTypeInputedCount++;
553 
554     for (auto pageIdComponmentsIter : componmentRecord.pageIdComponments) {
555         for (auto componmentVectorIter : pageIdComponmentsIter.second) {
556             if (componmentVectorIter.compare(inputCompMsgPtr->componmentType_) == 0) {
557                 componmentTypeTotal++;
558             }
559         }
560     }
561     if (componmentTypeInputedCount > componmentTypeTotal) {
562         componmentTypeInputedCount = componmentTypeTotal;
563     }
564 
565     componmentRecord.componmentTypeCount[inputCompMsgPtr->componmentType_] = componmentTypeInputedCount;
566     data["componment"] = inputCompMsgPtr->componmentType_;
567     data["inputedTimes"] = std::to_string(componmentTypeInputedCount);
568     data["componmentTotals"] = std::to_string(componmentTypeTotal);
569     DEBUG_LOG_STR("componmentType{%s} inputedTimes{%s} componmentTotals{%s}", data["componment"].c_str(),
570                   data["inputedTimes"].c_str(), data["componmentTotals"].c_str());
571     bundleComponmentRecord_[bundle] = componmentRecord;
572 }
573 
RecordScreenPath(const std::string & screenPath)574 void Report::RecordScreenPath(const std::string &screenPath)
575 {
576     TRACK_LOG_STD();
577     screenPaths_.push_back(screenPath);
578     TRACK_LOG_END();
579 }
580 
GetReportExceptionDir()581 std::string Report::GetReportExceptionDir()
582 {
583     return reportExceptionDir_;
584 }
585 }  // namespace WuKong
586 }  // namespace OHOS