1 /*
2 * Copyright (C) 2021 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 #include <iostream>
16 #include <sstream>
17 #include <filesystem>
18 #include <thread>
19 #include "unistd.h"
20 #include "include/sp_utils.h"
21 #include "include/ByTrace.h"
22 #include "include/sp_log.h"
23 #include "include/common.h"
24
25 namespace {
26 constexpr long long TIME_DIFF_THRESHOLD = 10000;
27 }
28 namespace OHOS {
29 namespace SmartPerf {
ItemData()30 std::map<std::string, std::string> ByTrace::ItemData()
31 {
32 return std::map<std::string, std::string>();
33 }
34
GetThreshold() const35 long long ByTrace::GetThreshold() const
36 {
37 long long jitters = jitterTimesTaken;
38 return jitters;
39 }
40
GetLowFps() const41 int ByTrace::GetLowFps() const
42 {
43 int lowfps = lowFps;
44 return lowfps;
45 }
46
SetByTrace()47 void ByTrace::SetByTrace()
48 {
49 std::vector<std::string> values;
50 std::string delimiter = "||";
51 std::string delim = "=";
52 size_t boundSize = 2;
53 SPUtils::StrSplit(jittersAndLowFps, delimiter, values);
54 bool jitterTimesTakenSet = false;
55 bool lowFpsSet = false;
56 for (std::string& vItem : values) {
57 std::vector<std::string> vItems;
58 SPUtils::StrSplit(vItem, delim, vItems);
59 if (vItems.size() >= boundSize) {
60 if (vItems[0] == "fpsJitterTime") {
61 jitterTimesTaken = SPUtilesTye::StringToSometype<int>(vItems[1]);
62 jitterTimesTakenSet = true;
63 }
64 if (vItems[0] == "lowFps") {
65 lowFps = SPUtilesTye::StringToSometype<int>(vItems[1]);
66 lowFpsSet = true;
67 }
68 }
69 }
70 if (!jitterTimesTakenSet || !lowFpsSet) {
71 LOGE("ByTrace::Missing required parameters in jittersAndLowFps");
72 return;
73 }
74 LOGD("ByTrace::SetByTrace jitterTimesTaken(%lld), lowFps(%d)", jitterTimesTaken, lowFps);
75 }
76
ClearTraceFiles() const77 void ByTrace::ClearTraceFiles() const
78 {
79 if (std::filesystem::exists(traceCpPath_)) {
80 RemoveTraceFiles();
81 }
82 }
83
RemoveTraceFiles() const84 void ByTrace::RemoveTraceFiles() const
85 {
86 if (std::filesystem::is_directory(traceCpPath_)) {
87 for (const auto& entry : std::filesystem::directory_iterator(traceCpPath_)) {
88 if (!entry.is_directory()) {
89 std::filesystem::remove(entry.path());
90 }
91 }
92 }
93 }
94
CpTraceFile() const95 void ByTrace::CpTraceFile() const
96 {
97 if (!std::filesystem::exists(traceCpPath_)) {
98 SPUtils::CreateDir(traceCpPath_);
99 }
100 if (!std::filesystem::is_directory(traceCpPath_)) {
101 LOGE("Destination path is not a directory.");
102 return;
103 }
104 std::string result;
105 std::string cpResult;
106 constexpr const char* cpCommand = "cp -r ";
107 constexpr const char* chmodCommand = "chmod 777 ";
108 const std::string cpHiviewTracePath = hiviewTracePath_ + hiviewTrace;
109 const std::string cpTrace = cpCommand + cpHiviewTracePath + " " + traceCpPath_;
110 if (!SPUtils::LoadCmd(cpTrace, result)) {
111 LOGE("Copy failed.");
112 return;
113 }
114 std::string tracePathChmod = chmodCommand + traceCpPath_;
115 if (!SPUtils::LoadCmd(tracePathChmod, result)) {
116 LOGE("Chmod failed.");
117 return;
118 }
119 LOGD("ByTrace::CpTraceFile result = (%s)", result.c_str());
120 }
121
CheckFpsJitters(long long & jitters,int cfps)122 void ByTrace::CheckFpsJitters(long long& jitters, int cfps)
123 {
124 times++;
125 const int two = 2;
126 if (times > two) {
127 nowTime = SPUtils::GetCurTime();
128 if (lastEnableTime > 0) {
129 long long diff =
130 (nowTime >= lastEnableTime) ? (nowTime - lastEnableTime) : (LLONG_MAX - lastEnableTime + nowTime + 1);
131 LOGD("ByTrace::Time difference: %llu ms", diff);
132 if (diff > TIME_DIFF_THRESHOLD) {
133 LOGW("ByTrace::Time difference exceeded threshold, resetting start capture time.");
134 lastEnableTime = 0;
135 }
136 }
137 SendSurfaceCaton(jitters, cfps);
138 }
139 }
140
SendSurfaceCaton(long long & jitters,int cfps)141 void ByTrace::SendSurfaceCaton(long long& jitters, int cfps)
142 {
143 if (cfps < lowFps || jitters > jitterTimesTaken) {
144 LOGD("ByTrace::SendSurfaceCaton jitters(%lld), cfps(%d)", jitters, cfps);
145 if (lastEnableTime == 0) {
146 lastEnableTime = nowTime;
147 ipcCallback_("surfaceCaton");
148 }
149 }
150 }
151 }
152 }
153