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 #ifndef SP_THREAD_SOCKET_H 16 #define SP_THREAD_SOCKET_H 17 #include <functional> 18 #include "sp_profiler_factory.h" 19 #include "sp_server_socket.h" 20 #include "sp_utils.h" 21 #include "sp_task.h" 22 #include "control_call_cmd.h" 23 #include "startup_delay.h" 24 #include "sp_log.h" 25 #include "common.h" 26 #include "heartbeat.h" 27 #include "Dubai.h" 28 namespace OHOS { 29 namespace SmartPerf { 30 class SpThreadSocket { 31 public: 32 static bool flagRunning; 33 static std::string resultFPS; MapToString(std::map<std::string, std::string> dataMap) const34 std::string MapToString(std::map<std::string, std::string> dataMap) const 35 { 36 std::string result; 37 int i = 0; 38 std::string splitStr = ""; 39 for (auto iter = dataMap.cbegin(); iter != dataMap.cend(); ++iter) { 40 printf("%s = %s\n", iter->first.c_str(), iter->second.c_str()); 41 if (i > 0) { 42 splitStr = "$$"; 43 } 44 result += splitStr + iter->first.c_str() + "||" + iter->second.c_str(); 45 i++; 46 } 47 return result; 48 } SplitMsg(const std::string &recvBuf) const49 std::string SplitMsg(const std::string &recvBuf) const 50 { 51 std::vector<std::string> sps; 52 SPUtils::StrSplit(recvBuf, "::", sps); 53 return sps[1]; 54 } 55 Process(ProtoType type) const56 void Process(ProtoType type) const 57 { 58 std::cout << "Socket Process called!" << std::endl; 59 LOGI("Socket Process called!"); 60 SpServerSocket spSocket; 61 spSocket.Init(type); 62 if (type == ProtoType::TCP) { 63 std::cout << "Socket TCP Init called!" << std::endl; 64 LOGI("Socket TCP Init called!"); 65 TypeTcp(spSocket); 66 } 67 if (type == ProtoType::UDP || type == ProtoType::UDPEX) { 68 LOGI("Socket UDP Init called! type(%d)", static_cast<int>(type)); 69 SocketHeartbeat(); 70 while (1) { 71 spSocket.Recvfrom(); 72 HandleMsg(spSocket); 73 } 74 } 75 std::cout << "Socket Process finished!" << std::endl; 76 LOGI("Socket Process finished!"); 77 spSocket.Close(); 78 } TypeTcp(SpServerSocket &spSocket) const79 void TypeTcp(SpServerSocket &spSocket) const 80 { 81 SocketHeartbeat(); 82 while (1) { 83 int procFd = spSocket.Accept(); 84 std::cout << "Socket TCP procFd: " << procFd << std::endl; 85 while (procFd > 0) { 86 int reFd = spSocket.Recv(); 87 if (reFd < 0) { 88 break; 89 } 90 std::string recvStr = spSocket.RecvBuf(); 91 std::cout << "Socket TCP Recv: " << recvStr << std::endl; 92 // 解析消息 分发处理 93 DealMsg(recvStr, spSocket); 94 } 95 } 96 } 97 // TCP InitRecv(std::string recvStr, SpServerSocket &spSocket) const98 void InitRecv(std::string recvStr, SpServerSocket &spSocket) const 99 { 100 std::string errorInfo; 101 std::string checkStr = recvStr.substr(std::string("init::").length()); 102 if (!SPTask::GetInstance().CheckTcpParam(checkStr, errorInfo)) { 103 LOGE("init error(%s) recvStr(%s)", errorInfo.c_str(), recvStr.c_str()); 104 spSocket.Send("init::False,\"error\":" + errorInfo); 105 return; 106 } 107 ErrCode code = SPTask::GetInstance().InitTask(SplitMsg(recvStr)); 108 LOGI("init::%s", (code == ErrCode::OK) ? "True" : "False"); 109 spSocket.Send(std::string("init::") + ((code == ErrCode::OK) ? "True" : "False")); 110 } StartRecv(SpServerSocket &spSocket) const111 void StartRecv(SpServerSocket &spSocket) const 112 { 113 if (flagRunning) { 114 LOGI("SP_daemon is running"); 115 spSocket.Send("SP_daemon is running"); 116 return; 117 } 118 auto lambdaTask = [](const std::string &data) { 119 std::cout << data << std::endl; 120 }; 121 ErrCode code = SPTask::GetInstance().StartTask(lambdaTask); 122 SPTask::GetInstance().StartRecord(); 123 LOGI("start:::%s", (code == ErrCode::OK) ? "True" : "False"); 124 if (code == ErrCode::OK) { 125 spSocket.Send("start::True"); 126 flagRunning = true; 127 } else if (code == ErrCode::FAILED) { 128 spSocket.Send("start::False"); 129 } 130 } StartRecvRealtime(SpServerSocket &spSocket) const131 void StartRecvRealtime(SpServerSocket &spSocket) const 132 { 133 auto lambdaTask = [&spSocket](const std::string &data) { spSocket.Send(data); }; 134 ErrCode code = SPTask::GetInstance().StartTask(lambdaTask); 135 LOGI("start::%s", (code == ErrCode::OK) ? "True" : "False"); 136 if (code == ErrCode::OK) { 137 spSocket.Send("start::True"); 138 } else if (code == ErrCode::FAILED) { 139 spSocket.Send("start::False"); 140 } 141 } StopRecvRealtime(SpServerSocket &spSocket) const142 void StopRecvRealtime(SpServerSocket &spSocket) const 143 { 144 SPTask::GetInstance().StopTask(); 145 LOGI("stop::True"); 146 spSocket.Send("stop::True"); 147 flagRunning = false; 148 spSocket.Close(); 149 } StartRecvRecord(SpServerSocket &spSocket) const150 void StartRecvRecord(SpServerSocket &spSocket) const 151 { 152 LOGI("startRecord::True"); 153 SPTask::GetInstance().StartRecord(); 154 155 spSocket.Send("startRecord::True"); 156 } StopRecvRecord(SpServerSocket &spSocket) const157 void StopRecvRecord(SpServerSocket &spSocket) const 158 { 159 LOGI("stopRecord::True"); 160 SPTask::GetInstance().StopRecord(); 161 162 spSocket.Send("stopRecord::True"); 163 } DealMsg(std::string recvStr, SpServerSocket &spSocket) const164 void DealMsg(std::string recvStr, SpServerSocket &spSocket) const 165 { 166 SocketHeartbeat(); 167 if (recvStr.find("init::") != std::string::npos) { 168 InitRecv(recvStr, spSocket); 169 } else if (recvStr.find("start:::") != std::string::npos) { 170 StartRecv(spSocket); 171 } else if (recvStr.find("start::") != std::string::npos) { 172 StartRecvRealtime(spSocket); 173 } else if (recvStr.find("stop::") != std::string::npos) { 174 StopRecvRealtime(spSocket); 175 } else if (recvStr.find("startRecord::") != std::string::npos) { 176 StartRecvRecord(spSocket); 177 } else if (recvStr.find("stopRecord::") != std::string::npos) { 178 StopRecvRecord(spSocket); 179 } else if (recvStr.find("SP_daemon -editor") != std::string::npos) { 180 EditorRecv(recvStr, spSocket); 181 } 182 } EditorRecv(std::string recvStr, const SpServerSocket &spSocket) const183 void EditorRecv(std::string recvStr, const SpServerSocket &spSocket) const 184 { 185 std::vector<std::string> vec; 186 size_t size = recvStr.size(); 187 size_t j = 0; 188 for (size_t i = 0; i < size; i++) { 189 if (recvStr[i] == ' ') { 190 vec.push_back(recvStr.substr(j, i - j)); 191 j = i + 1; 192 } 193 } 194 vec.push_back(recvStr.substr(j, size - j)); 195 const int type = 2; 196 if (vec[type] == "findAppPage") { 197 BackDesktop(); 198 } 199 OHOS::SmartPerf::ControlCallCmd controlCallCmd; 200 std::string result = controlCallCmd.GetResult(vec); 201 spSocket.Send(result); 202 } 203 BackDesktop() const204 void BackDesktop() const 205 { 206 std::string cmdResult; 207 std::string uinput = CMD_COMMAND_MAP.at(CmdCommand::UINPUT_BACK); 208 SPUtils::LoadCmd(uinput, cmdResult); 209 } 210 211 // UDP HandleMsg(SpServerSocket &spSocket) const212 void HandleMsg(SpServerSocket &spSocket) const 213 { 214 std::string retCode = ""; 215 auto iterator = MESSAGE_MAP.begin(); 216 while (iterator != MESSAGE_MAP.end()) { 217 std::string recvBuf = spSocket.RecvBuf(); 218 if (recvBuf.size() != 0) { 219 Heartbeat &heartbeat = Heartbeat::GetInstance(); 220 heartbeat.UpdatestartTime(); 221 } 222 if (!SPUtils::IsSubString(recvBuf, iterator->second)) { 223 ++iterator; 224 continue; 225 } 226 SpProfiler *profiler = SpProfilerFactory::GetProfilerItem(iterator->first); 227 if (profiler == nullptr) { 228 HandleNullMsg(spSocket, profiler, retCode, recvBuf, iterator); 229 } else { 230 std::map<std::string, std::string> data; 231 if (iterator->first == MessageType::CATCH_NETWORK_TRAFFIC) { 232 profiler->ItemData(); // record the collection point for the first time,no need to return 233 data["network_traffic"] = "true"; 234 } else if (iterator->first == MessageType::GET_NETWORK_TRAFFIC) { 235 data = profiler->ItemData(); 236 data["network_traffic"] = "true"; 237 } else { 238 data = profiler->ItemData(); 239 } 240 HandleUDPMsg(spSocket, data, retCode, iterator); 241 } 242 LOGI("sendData key(%d) content(%s)", iterator->first, retCode.c_str()); 243 break; 244 } 245 } HandleUDPMsg(SpServerSocket &spSocket, std::map<std::string, std::string> data, std::string retCode, std::unordered_map<MessageType, std::string>::const_iterator iterator) const246 void HandleUDPMsg(SpServerSocket &spSocket, std::map<std::string, std::string> data, std::string retCode, 247 std::unordered_map<MessageType, std::string>::const_iterator iterator) const 248 { 249 std::cout << "iterator->first: " << static_cast<int>(iterator->first) << std::endl; 250 if (iterator->first == MessageType::GET_LOW_POWER_FPS) { 251 for (auto iter = data.cbegin(); iter != data.cend(); ++iter) { 252 if (iter->first != "fpsJitters") { 253 std::string temp = iter->second + "@@"; 254 resultFPS += std::string(temp.c_str()); 255 } 256 } 257 } else if (iterator->first == MessageType::GET_CUR_FPS) { 258 std::string resultfps = "vfps||"; 259 for (auto iter = data.cbegin(); iter != data.cend(); ++iter) { 260 if (iter->first != "fpsJitters") { 261 std::string temp = iter->second + "@@"; 262 resultFPS += std::string(temp.c_str()); 263 resultfps += std::string(temp.c_str()); 264 } 265 } 266 spSocket.Sendto(resultfps); 267 } else if (iterator->first == MessageType::GET_CPU_FREQ_LOAD) { 268 FetchCpuStats(spSocket, data); 269 } else { 270 retCode = MapToString(data); 271 spSocket.Sendto(retCode); 272 } 273 } SocketHeartbeat() const274 void SocketHeartbeat() const 275 { 276 Heartbeat &heartbeat = Heartbeat::GetInstance(); 277 heartbeat.UpdatestartTime(); 278 } FetchCpuStats(SpServerSocket &spSocket, std::map<std::string, std::string> data) const279 void FetchCpuStats(SpServerSocket &spSocket, std::map<std::string, std::string> data) const 280 { 281 std::string resultCpuFrequency = ""; 282 std::string resultCpuUsage = ""; 283 std::string resultCpu = ""; 284 int cpuFrequencyNum = 0; 285 int cpuUsageNum = 0; 286 int cpuFlag = 1; 287 while (cpuFlag) { 288 resultCpuFrequency = "cpu" + std::to_string(cpuFrequencyNum) + "Frequency"; 289 resultCpuUsage = "cpu" + std::to_string(cpuUsageNum) + "Usage"; 290 auto iterCpuFrequency = data.find(resultCpuFrequency); 291 auto iterCpuUsage = data.find(resultCpuUsage); 292 if (iterCpuFrequency != data.end()) { 293 resultCpuFrequency += "||" + iterCpuFrequency->second; 294 resultCpu += "$$" + resultCpuFrequency; 295 cpuFrequencyNum++; 296 } else { 297 cpuFlag = 0; 298 } 299 if (iterCpuUsage != data.end()) { 300 resultCpuUsage += "||" + iterCpuUsage->second; 301 resultCpu += "$$" + resultCpuUsage; 302 cpuUsageNum++; 303 } else { 304 cpuFlag = 0; 305 } 306 } 307 spSocket.Sendto(resultCpu); 308 } HandleNullMsg(SpServerSocket &spSocket, SpProfiler *profiler, std::string retCode, std::string recvBuf, std::unordered_map<MessageType, std::string>::const_iterator iterator) const309 void HandleNullMsg(SpServerSocket &spSocket, SpProfiler *profiler, std::string retCode, std::string recvBuf, 310 std::unordered_map<MessageType, std::string>::const_iterator iterator) const 311 { 312 if (iterator->first == MessageType::SET_PKG_NAME) { 313 retCode = SplitMsg(recvBuf); 314 if (retCode.find("smartperf") != std::string::npos) { 315 OHOS::SmartPerf::Dubai::dubaiPkgName = retCode; 316 } 317 std::string processId = ""; 318 OHOS::SmartPerf::StartUpDelay sp; 319 processId = sp.GetPidByPkg(retCode); 320 SpProfilerFactory::SetProfilerPidByPkg(processId); 321 SpProfilerFactory::SetProfilerPkg(retCode); 322 spSocket.Sendto(retCode); 323 } else if (iterator->first == MessageType::FPS_STOP) { 324 spSocket.Sendto(resultFPS); 325 resultFPS = "FPS||"; 326 } else if (profiler == nullptr && (iterator->first == MessageType::SET_GAME_VIEW)) { 327 retCode = SplitMsg(recvBuf); 328 SpProfilerFactory::SetProfilerGameLayer(retCode); 329 } else if (iterator->first == MessageType::CATCH_TRACE_CONFIG || 330 iterator->first == MessageType::CATCH_TRACE_CMD) { 331 SpProfilerFactory::SetByTrace(SplitMsg(recvBuf)); 332 } else if (iterator->first == MessageType::GET_CPU_NUM) { 333 retCode = SPUtils::GetCpuNum(); 334 spSocket.Sendto(retCode); 335 } else if (iterator->first == MessageType::BACK_TO_DESKTOP) { 336 BackDesktop(); 337 } else { 338 retCode = iterator->second; 339 spSocket.Sendto(retCode); 340 LOGI("UDP sendData: (%s)", retCode.c_str()); 341 } 342 } 343 }; 344 bool SpThreadSocket::flagRunning = false; 345 std::string SpThreadSocket::resultFPS = "FPS||"; 346 } 347 } 348 #endif