1
2 /*
3 * Copyright (C) 2021 Huawei Device Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <netinet/in.h>
17 #include <sys/socket.h>
18 #include <arpa/inet.h>
19 #include <unistd.h>
20 #include <iostream>
21 #include <functional>
22 #include <vector>
23 #include <thread>
24 #include <future>
25 #include <map>
26 #include <mutex>
27 #include <climits>
28 #include "parameters.h"
29 #include "include/sp_csv_util.h"
30 #include "include/sdk_data_recv.h"
31 #include "include/GpuCounter.h"
32 #include "include/lock_frequency.h"
33 #include "include/sp_thread_socket.h"
34 #include "include/sp_profiler_factory.h"
35 #include "include/sp_log.h"
36 #include "include/sp_task.h"
37 #include "include/heartbeat.h"
38 #include "include/control_call_cmd.h"
39 #include "include/sp_profiler_factory.h"
40 #include "include/Network.h"
41 #include "include/startup_delay.h"
42 #include "include/Dubai.h"
43 #include "include/GameEvent.h"
44 #include "include/GetLog.h"
45 #include "include/RAM.h"
46 #include "include/FPS.h"
47 #include "include/hiperf.h"
48
49 #define SMARTPERF "smartperf"
50 namespace OHOS {
51 namespace SmartPerf {
52 std::string g_pkgName = "";
53 std::string g_pkgAndPid = "";
MapToString(std::map<std::string,std::string> & dataMap) const54 std::string SpThreadSocket::MapToString(std::map<std::string, std::string>& dataMap) const
55 {
56 std::string result;
57 int i = 0;
58 std::string splitStr = "";
59 for (auto iter = dataMap.cbegin(); iter != dataMap.cend(); ++iter) {
60 printf("%s = %s\n", iter->first.c_str(), iter->second.c_str());
61 if (i > 0) {
62 splitStr = "$$";
63 }
64 result += splitStr + iter->first.c_str() + "||" + iter->second.c_str();
65 i++;
66 }
67 return result;
68 }
SplitMsg(const std::string & recvBuf) const69 std::string SpThreadSocket::SplitMsg(const std::string &recvBuf) const
70 {
71 if (recvBuf.empty()) {
72 LOGE("SplitMsg recvBuf is null");
73 return recvBuf;
74 }
75 size_t pos = recvBuf.find("::");
76 if (pos != std::string::npos) {
77 std::vector<std::string> sps;
78 SPUtils::StrSplit(recvBuf, "::", sps);
79 if (sps.size() > 1) {
80 return sps[1];
81 } else {
82 LOGE("SplitMsg sps size is zreo");
83 return recvBuf;
84 }
85 } else {
86 return recvBuf;
87 }
88 }
89
Process(ProtoType type)90 void SpThreadSocket::Process(ProtoType type)
91 {
92 std::cout << "Socket Process called!" << std::endl;
93 SpServerSocket spSocket;
94 spSocket.Init(type);
95 if (type == ProtoType::TCP) {
96 std::cout << "Socket TCP Init called!" << std::endl;
97 WLOGI("Socket TCP Init called!");
98 TypeTcp(spSocket);
99 }
100 if (type == ProtoType::UDP || type == ProtoType::UDPEX) {
101 SocketHeartbeat();
102 while (socketConnect == true) {
103 spSocket.Recvfrom();
104 HandleMsg(spSocket);
105 }
106 }
107 std::cout << "Socket Process finished!" << std::endl;
108 spSocket.Close();
109 }
CheckTcpToken(const std::string & recvStr,SpServerSocket & spSocket,const std::string & recvStrNoToken) const110 SocketErrorType SpThreadSocket::CheckTcpToken(const std::string& recvStr,
111 SpServerSocket &spSocket, const std::string& recvStrNoToken) const
112 {
113 if (recvStr.find_last_of(":") == std::string::npos) {
114 if (recvStr.find("SP_daemon -editor") != std::string::npos) {
115 LOGI("Received string contains 'SP_daemon -editor', token check passed.");
116 return SocketErrorType::OK;
117 } else {
118 LOGE("Token check failed: %s", recvStrNoToken.c_str());
119 return SocketErrorType::TOKEN_CHECK_FAILED;
120 }
121 }
122 std::string token = recvStr.substr(recvStr.find_last_of(":") + 1);
123 token = token.substr(0, token.find(' '));
124 std::string tcpSocketToken = SpThreadSocket::GetInstance().GetToken();
125 LOGD("Comparing token with TCP token...");
126 if (tcpSocketToken == "" && token == "-SESSIONID") {
127 LOGI("Token is empty but received token is '-SESSIONID', token check passed.");
128 return SocketErrorType::OK;
129 }
130 if (token != tcpSocketToken) {
131 LOGE("Token mismatch.");
132 return SocketErrorType::TOKEN_CHECK_FAILED;
133 }
134 LOGD("Token match");
135 return SocketErrorType::OK;
136 }
TypeTcp(SpServerSocket & spSocket)137 void SpThreadSocket::TypeTcp(SpServerSocket &spSocket)
138 {
139 SocketHeartbeat();
140 WLOGI("Socket TCP Init Finished, Wait Client Socket Connect...");
141 while (socketConnect == true) {
142 int procFd = spSocket.Accept();
143 std::cout << "Socket TCP procFd: " << procFd << std::endl;
144 WLOGI("Accepted socket connection, procFd: %d", procFd);
145 while (procFd > 0) {
146 int reFd = spSocket.Recv();
147 if (reFd < 0) {
148 WLOGE("Error receiving data, reFd: %d", reFd);
149 break;
150 }
151 std::string recvStr = spSocket.RecvBuf();
152 std::string recvStrNoToken = recvStr.substr(0, recvStr.find("::"));
153 LOGD("TCP recv data:%s", recvStr.c_str());
154 WLOGD("Received data: %s", recvStrNoToken.c_str());
155 // 解析消息 分发处理
156 const SocketErrorType tokenStatus = CheckTcpToken(recvStr, spSocket, recvStrNoToken);
157 WLOGI("Token check status: %d", tokenStatus);
158 DealMsg(recvStr, spSocket, tokenStatus);
159 }
160 }
161 }
162 // TCP
InitRecv(const std::string & recvStr,SpServerSocket & spSocket,SocketConnectType type) const163 void SpThreadSocket::InitRecv(const std::string& recvStr, SpServerSocket &spSocket, SocketConnectType type) const
164 {
165 std::string errorInfo;
166 std::string checkStr = recvStr.substr(std::string("init::").length());
167 if (!SPTask::GetInstance().CheckTcpParam(checkStr, errorInfo) &&
168 checkStr.find(SpThreadSocket::GetInstance().GetToken()) == std::string::npos) {
169 WLOGE("Init error(%s)", errorInfo.c_str());
170 if (type == SocketConnectType::CMD_SOCKET) {
171 spSocket.Send("init::False,\"error\":" + errorInfo);
172 } else {
173 spSocket.Send(std::string("init::") + SocketErrorTypeToString(SocketErrorType::INIT_FAILED));
174 }
175 return;
176 }
177 if (recvStr.find("-lockfreq") != std::string::npos && SpThreadSocket::GetInstance().GetToken() == "") {
178 WLOGE("'-lockfreq' must have a valid token.");
179 return;
180 }
181 ErrCode code = SPTask::GetInstance().InitTask(SplitMsg(recvStr));
182 if (type == SocketConnectType::CMD_SOCKET) {
183 spSocket.Send(std::string("init::") + ((code == ErrCode::OK) ? "True" : "False"));
184 WLOGI("Sent init::" + ((code == ErrCode::OK) ? "True" : "False"));
185 return;
186 }
187 if (code == ErrCode::OK) {
188 spSocket.Send("init::True");
189 WLOGI("Sent init::True response");
190 } else {
191 spSocket.Send(std::string("init::") + SocketErrorTypeToString(SocketErrorType::INIT_FAILED));
192 WLOGE("Sent init::%d for failure", SocketErrorType::INIT_FAILED);
193 }
194 }
StartRecv(SpServerSocket & spSocket)195 void SpThreadSocket::StartRecv(SpServerSocket &spSocket)
196 {
197 if (flagRunning) {
198 spSocket.Send("SP_daemon is running");
199 return;
200 }
201 auto lambdaTask = [](const std::string &data) {
202 std::cout << data << std::endl;
203 };
204 ErrCode code = SPTask::GetInstance().StartTask(lambdaTask);
205 if (code == ErrCode::OK) {
206 spSocket.Send("start::True");
207 flagRunning = true;
208 WLOGI("Sent start::True message to socket.");
209 } else if (code == ErrCode::FAILED) {
210 spSocket.Send("start::False");
211 WLOGE("Sent start::False message to socket.");
212 return;
213 }
214 SPTask::GetInstance().StartRecord();
215 }
StartRecvRealtime(SpServerSocket & spSocket) const216 void SpThreadSocket::StartRecvRealtime(SpServerSocket &spSocket) const
217 {
218 auto lambdaTask = [&spSocket](const std::string &data) { spSocket.Send(data); };
219 ErrCode code = SPTask::GetInstance().StartTask(lambdaTask);
220 if (code == ErrCode::OK) {
221 spSocket.Send("start::True");
222 WLOGI("Sent start::True message to socket.");
223 } else if (code == ErrCode::FAILED) {
224 spSocket.Send(std::string("start::") + SocketErrorTypeToString(SocketErrorType::START_FAILED));
225 WLOGE("Sent start::" + SocketErrorTypeToString(SocketErrorType::START_FAILED) + " message to socket.");
226 }
227 }
StopRecvRealtime(SpServerSocket & spSocket)228 void SpThreadSocket::StopRecvRealtime(SpServerSocket &spSocket)
229 {
230 ErrCode code = SPTask::GetInstance().StopTask();
231 if (code == ErrCode::OK) {
232 spSocket.Send("stop::True");
233 WLOGI("Sent stop::True message to socket.");
234 flagRunning = false;
235 spSocket.Close();
236 } else if (code == ErrCode::FAILED) {
237 spSocket.Send(std::string("stop::") + SocketErrorTypeToString(SocketErrorType::STOP_FAILED));
238 WLOGE("Sent stop::" + SocketErrorTypeToString(SocketErrorType::STOP_FAILED) + " message to socket.");
239 }
240 }
StartRecvRecord(SpServerSocket & spSocket) const241 void SpThreadSocket::StartRecvRecord(SpServerSocket &spSocket) const
242 {
243 ErrCode code = SPTask::GetInstance().StartRecord();
244 if (code == ErrCode::OK) {
245 spSocket.Send("startRecord::True");
246 WLOGI("Sent startRecord::True message to socket.");
247 } else {
248 spSocket.Send(std::string("startRecord::") + SocketErrorTypeToString(SocketErrorType::START_RECORD_FAILED));
249 WLOGE("Sent startRecord::" + SocketErrorTypeToString(SocketErrorType::START_RECORD_FAILED) +
250 " message to socket.");
251 }
252 }
StopRecvRecord(SpServerSocket & spSocket) const253 void SpThreadSocket::StopRecvRecord(SpServerSocket &spSocket) const
254 {
255 ErrCode code = SPTask::GetInstance().StopRecord();
256 if (code == ErrCode::OK) {
257 spSocket.Send("stopRecord::True");
258 WLOGI("Sent stopRecord::True message to socket.");
259 } else {
260 spSocket.Send(std::string("stopRecord::") + SocketErrorTypeToString(SocketErrorType::STOP_RECORD_FAILED));
261 WLOGE("Sent stopRecord::" + SocketErrorTypeToString(SocketErrorType::STOP_RECORD_FAILED) +
262 " message to socket.");
263 }
264 }
SendTokenFailedMessage(SpServerSocket & socket,const std::string & message) const265 void SpThreadSocket::SendTokenFailedMessage(SpServerSocket &socket, const std::string &message) const
266 {
267 if (message.find("init:::") != std::string::npos ||
268 message.find("start:::") != std::string::npos) {
269 WLOGI("Skipping token check failure for init::: or start::: command.");
270 return;
271 }
272 const std::vector<std::string> messageType = {
273 "init::",
274 "start::",
275 "stop::",
276 "startRecord::",
277 "stopRecord::",
278 };
279 for (auto& it : messageType) {
280 if (message.find(it) != std::string::npos) {
281 WLOGE("Sending token check failed message for command: %s", it.c_str());
282 socket.Send(it + SocketErrorTypeToString(SocketErrorType::TOKEN_CHECK_FAILED));
283 return;
284 }
285 }
286 WLOGW("No matching command found for token check failure in message: %s", message.c_str());
287 }
CheckUdpToken(const std::string & recvStr) const288 SocketErrorType SpThreadSocket::CheckUdpToken(const std::string& recvStr) const
289 {
290 // 不需要校验 token
291 if (isNeedUdpToken == false) {
292 return SocketErrorType::OK;
293 }
294 // device 启动时发送,不做校验
295 if (recvStr == "get_daemon_version" || recvStr.find("set_pkgName::") != std::string::npos) {
296 return SocketErrorType::OK;
297 }
298 // command:::token
299 if (recvStr.find_last_of(":::") == std::string::npos) {
300 WLOGE("Token check failed: %s", recvStr.c_str());
301 return SocketErrorType::TOKEN_CHECK_FAILED;
302 }
303 // 提取 token
304 std::string token = recvStr.substr(recvStr.find_last_of(":::") + 1);
305 token = token.substr(0, token.find(' '));
306
307 std::string udpSocketToken = SpThreadSocket::GetInstance().GetToken();
308 LOGD("Comparing token with Udp token...");
309 // token 校验
310 if (token != udpSocketToken) {
311 WLOGE("Token mismatch.");
312 return SocketErrorType::TOKEN_CHECK_FAILED;
313 }
314 LOGD("UDP token check passed");
315 return SocketErrorType::OK;
316 }
DealMsg(const std::string & recvStr,SpServerSocket & spSocket,SocketErrorType tokenStatus)317 void SpThreadSocket::DealMsg(const std::string& recvStr, SpServerSocket &spSocket, SocketErrorType tokenStatus)
318 {
319 SocketHeartbeat();
320 if (tokenStatus == SocketErrorType::TOKEN_CHECK_FAILED) {
321 SendTokenFailedMessage(spSocket, recvStr);
322 return;
323 }
324 if (recvStr.find("init:::") != std::string::npos) {
325 WLOGI("Processing 'init:::' command.");
326 InitRecv(recvStr, spSocket, SocketConnectType::CMD_SOCKET);
327 FPS::GetInstance().isNeedDump = true;
328 } else if (recvStr.find("start:::") != std::string::npos) {
329 WLOGI("Processing 'start:::' command.");
330 StartRecv(spSocket);
331 } else if (recvStr.find("init::") != std::string::npos) {
332 WLOGI("Processing 'init::' command.");
333 InitRecv(recvStr, spSocket, SocketConnectType::EDITOR_SOCKET);
334 } else if (recvStr.find("start::") != std::string::npos) {
335 WLOGI("Processing 'start::' command.");
336 StartRecvRealtime(spSocket);
337 } else if (recvStr.find("stop::") != std::string::npos) {
338 WLOGI("Processing 'stop::' command.");
339 SpProfilerFactory::editorFlag = false;
340 StopRecvRealtime(spSocket);
341 } else if (recvStr.find("startRecord::") != std::string::npos) {
342 WLOGI("Processing 'startRecord::' command.");
343 StartRecvRecord(spSocket);
344 } else if (recvStr.find("stopRecord::") != std::string::npos) {
345 WLOGI("Processing 'stopRecord::' command.");
346 SpProfilerFactory::editorFlag = false;
347 StopRecvRecord(spSocket);
348 } else if (recvStr.find("SP_daemon -editor") != std::string::npos) {
349 EditorRecv(recvStr, spSocket);
350 } else {
351 WLOGW("Received unknown command: %s", recvStr.c_str());
352 }
353 }
EditorRecv(const std::string & recvStr,const SpServerSocket & spSocket) const354 void SpThreadSocket::EditorRecv(const std::string& recvStr, const SpServerSocket &spSocket) const
355 {
356 std::vector<std::string> vec;
357 size_t size = recvStr.size();
358 size_t j = 0;
359 for (size_t i = 0; i < size; i++) {
360 if (recvStr[i] == ' ') {
361 vec.push_back(recvStr.substr(j, i - j));
362 j = i + 1;
363 }
364 }
365 vec.push_back(recvStr.substr(j, size - j));
366 const int type = 2;
367 if (vec[type] == "findAppPage") {
368 BackDesktop();
369 }
370 OHOS::SmartPerf::ControlCallCmd controlCallCmd;
371 std::string result = controlCallCmd.GetResult(vec);
372 spSocket.Send(result);
373 }
BackDesktop() const374 void SpThreadSocket::BackDesktop() const
375 {
376 std::string cmdResult;
377 std::string uinput = CMD_COMMAND_MAP.at(CmdCommand::UINPUT_BACK);
378 SPUtils::LoadCmd(uinput, cmdResult);
379 }
380 // UDP
RemoveToken(std::string & recvMessage)381 void SpThreadSocket::RemoveToken(std::string &recvMessage)
382 {
383 if (recvMessage.find(":::") != std::string::npos) {
384 recvMessage = recvMessage.substr(0, recvMessage.find(":::"));
385 }
386 }
387
HandleMsg(SpServerSocket & spSocket)388 void SpThreadSocket::HandleMsg(SpServerSocket &spSocket)
389 {
390 std::string retCode = "";
391 auto iterator = MESSAGE_MAP.begin();
392 while (iterator != MESSAGE_MAP.end()) {
393 std::string recvBuf = spSocket.RecvBuf();
394 HeartbeatDetection(recvBuf);
395 const SocketErrorType tokenStatus = CheckUdpToken(recvBuf);
396 if (tokenStatus == SocketErrorType::TOKEN_CHECK_FAILED) {
397 std::string failStr = std::string("token failed");
398 spSocket.Sendto(failStr);
399 spSocket.Close();
400 return;
401 }
402 RemoveToken(recvBuf);
403 if (recvBuf.find("init::") != std::string::npos && firstFlag) {
404 HandleMsgTrace(recvBuf);
405 UdpStartInitFunc(recvBuf, spSocket);
406 firstFlag = false;
407 break;
408 }
409 if (!SPUtils::IsSubString(recvBuf, iterator->second)) {
410 ++iterator;
411 continue;
412 }
413 LOGD("UDP recv : %s", recvBuf.c_str());
414 SpProfiler *profiler = SpProfilerFactory::GetProfilerItem(iterator->first);
415 if (profiler == nullptr) {
416 HandleNullMsg(spSocket, profiler, retCode, recvBuf, iterator);
417 } else {
418 std::map<std::string, std::string> data;
419 if (iterator->first == MessageType::CATCH_NETWORK_TRAFFIC) {
420 Network::GetInstance().IsFindHap();
421 profiler->ItemData(); // record the collection point for the first time,no need to return
422 data["network_traffic"] = "true";
423 } else if (iterator->first == MessageType::GET_NETWORK_TRAFFIC) {
424 Network::GetInstance().IsStopFindHap();
425 data = profiler->ItemData();
426 data["network_traffic"] = "true";
427 } else if (iterator->first == MessageType::GET_LOG) {
428 GetSocketPort(recvBuf);
429 data = profiler->ItemData();
430 } else {
431 GetProcessIdByPkgName(iterator);
432 data = profiler->ItemData();
433 }
434 HandleUDPMsg(spSocket, data, retCode, iterator);
435 }
436 break;
437 }
438 }
439
HandleMsgTrace(std::string & recvMessage)440 void SpThreadSocket::HandleMsgTrace(std::string& recvMessage)
441 {
442 const std::string traceWord = "-TRACE::";
443 const size_t startPos = recvMessage.find(traceWord);
444 const size_t tarceLength = traceWord.length();
445 const size_t colonLength = 2;
446 if (startPos != std::string::npos) {
447 size_t tracePos = startPos + tarceLength;
448 size_t endPos = recvMessage.find(" ", startPos);
449 bytrace.jittersAndLowFps = recvMessage.substr(tracePos, endPos - tracePos);
450 recvMessage.erase(tracePos - colonLength, colonLength + bytrace.jittersAndLowFps.length());
451 }
452 }
453
HeartbeatDetection(const std::string & recvBuf)454 void SpThreadSocket::HeartbeatDetection(const std::string& recvBuf)
455 {
456 if (recvBuf.size() != 0) {
457 Heartbeat &heartbeat = Heartbeat::GetInstance();
458 heartbeat.UpdatestartTime();
459 }
460 }
461
UdpStartInitFunc(const std::string & recvBuf,SpServerSocket & spSocket)462 void SpThreadSocket::UdpStartInitFunc(const std::string& recvBuf, SpServerSocket &spSocket)
463 {
464 if (taskMgr_ != nullptr) {
465 taskMgr_->Stop();
466 taskMgr_->WriteToCSV();
467 }
468 taskMgr_ = std::make_shared<TaskManager>(true);
469 auto lambdaTask = [&spSocket](const std::string &data) { spSocket.Sendto(data); };
470 taskMgr_->SetIPCCallback(lambdaTask);
471 taskMgr_->AddTask(recvBuf);
472 spTask.SetAppCmd(recvBuf);
473 spTask.SetAppInitFlag();
474
475 std::string fileDir = "/data/local/tmp/smartperf/" + spTask.GetCurTaskInfo().sessionId;
476 spTask.CreatPath(fileDir);
477 taskMgr_->SetFilePath(fileDir + "/t_index_info.csv");
478 }
479
FileSocketConnect()480 int SpThreadSocket::FileSocketConnect()
481 {
482 sendFileSocket = socket(AF_INET, SOCK_STREAM, 0);
483 if (sendFileSocket < 0) {
484 WLOGE("Create log file socket failed, errno: %d", errno);
485 return -1;
486 }
487 struct sockaddr_in socketAddr = {0};
488 socketAddr.sin_family = AF_INET;
489 socketAddr.sin_port = htons(sendFileSocketPort);
490 socketAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
491 if (connect(sendFileSocket, reinterpret_cast<struct sockaddr *>(&socketAddr), sizeof(socketAddr)) < 0) {
492 WLOGE("Connect log file socket failed, errno: %d", errno);
493 return -1;
494 }
495 WLOGI("Connect log file socket success, socket: %d", sendFileSocket);
496 return sendFileSocket;
497 }
498
SendFile(const std::string & filePath)499 int SpThreadSocket::SendFile(const std::string& filePath)
500 {
501 char filePathChar[PATH_MAX] = {0x00};
502 if ((realpath(filePath.c_str(), filePathChar) == nullptr)) {
503 WLOGE("%s is not exist.", filePath.c_str());
504 return -1;
505 }
506 std::ifstream logFile(filePathChar, std::ios::binary);
507 if (!logFile.is_open()) {
508 WLOGE("Open log file failed");
509 close(sendFileSocket);
510 sendFileSocket = -1;
511 return -1;
512 }
513 WLOGI("logfile exists, sending...");
514 logFile.seekg(0, std::ios::end);
515 std::streamsize fileSize = logFile.tellg();
516 logFile.seekg(0, std::ios::beg);
517 std::streamsize totalSent = 0;
518 while (!logFile.eof()) {
519 logFile.read(fileSocketBuffer, sizeof(fileSocketBuffer));
520 std::streamsize bytesRead = logFile.gcount();
521 ssize_t bytesSent = send(sendFileSocket, fileSocketBuffer, bytesRead, 0);
522 if (bytesSent < 0) {
523 WLOGE("Send log file failed");
524 logFile.close();
525 close(sendFileSocket);
526 sendFileSocket = -1;
527 return -1;
528 }
529 totalSent += bytesSent;
530 if (bytesSent != bytesRead) {
531 WLOGE("Incomplete send: sent %zd bytes out of %zd", bytesSent, bytesRead);
532 logFile.close();
533 close(sendFileSocket);
534 sendFileSocket = -1;
535 return -1;
536 }
537 }
538 if (totalSent != fileSize) {
539 WLOGE("File size mismatch: sent %zd bytes, file size %zd", totalSent, fileSize);
540 return -1;
541 }
542 logFile.close();
543 close(sendFileSocket);
544 sendFileSocket = -1;
545 WLOGI("Send log file success, bytes: %zd", totalSent);
546 return 0;
547 }
548
ConnectAndSendFile(SpServerSocket & spSocket,const std::string filePath)549 void SpThreadSocket::ConnectAndSendFile(SpServerSocket &spSocket, const std::string filePath)
550 {
551 if (filePath.empty()) {
552 WLOGE("Connect filePath does not exist.");
553 return;
554 }
555 if (sendFileSocketPort == -1) {
556 return;
557 }
558 std::thread sendSizeThread([&spSocket, filePath]() {
559 size_t fileSize = SPUtils::GetFileSize(filePath);
560 if (fileSize == 0) {
561 LOGE("UDP ConnectAndSendFile recv GetFileSize fileSize: (%d)", fileSize);
562 return;
563 }
564 std::string sendFileSizeMsg = "SendFileSize:::" + std::to_string(fileSize);
565 LOGI("UDP START sendFileSizeMsg = %s", sendFileSizeMsg.c_str());
566 spSocket.Sendto(sendFileSizeMsg);
567 LOGI("UDP Sendto sendFileSizeMsg = %s", sendFileSizeMsg.c_str());
568 });
569
570 std::thread sendFileThread([this, filePath]() {
571 int fileSocket = -1;
572 int connectCount = 0;
573 const int maxTryCount = 2;
574
575 while (fileSocket < 0) {
576 WLOGI("Connect file log socket, try times: %d", connectCount + 1);
577 if (connectCount > maxTryCount) {
578 WLOGE("Connect file log socket failed");
579 return;
580 }
581 connectCount++;
582 fileSocket = FileSocketConnect();
583 }
584
585 int ret = SendFile(filePath);
586 if (ret < 0) {
587 WLOGE("Failed to send file");
588 return;
589 }
590 });
591
592 sendSizeThread.join();
593 sendFileThread.join();
594 }
595
HandleUDPMsg(SpServerSocket & spSocket,std::map<std::string,std::string> & data,std::string & retCode,std::unordered_map<MessageType,std::string>::const_iterator iterator)596 void SpThreadSocket::HandleUDPMsg(SpServerSocket &spSocket, std::map<std::string, std::string>& data,
597 std::string& retCode, std::unordered_map<MessageType, std::string>::const_iterator iterator)
598 {
599 std::cout << "iterator->first: " << static_cast<int>(iterator->first) << std::endl;
600 if (iterator->first == MessageType::GET_CUR_FPS) {
601 FPS::GetInstance().isLowCurFps = true;
602 std::string resultfps = "vfps||";
603 for (auto iter = data.cbegin(); iter != data.cend(); ++iter) {
604 if (iter->first != "fpsJitters") {
605 std::string temp = iter->second + "@@";
606 resultfps += std::string(temp.c_str());
607 }
608 }
609 spSocket.Sendto(resultfps);
610 LOGD("UDP send Cur_resultfps = %s", resultfps.c_str());
611 } else if (iterator->first == MessageType::GET_CPU_FREQ_LOAD) {
612 FetchCpuStats(spSocket, data);
613 } else if (iterator->first == MessageType::GET_LOG) {
614 ConnectAndSendFile(spSocket, logFilePath);
615 GetLog::GetInstance().RemoveLogFile();
616 } else {
617 retCode = MapToString(data);
618 spSocket.Sendto(retCode);
619 LOGD("UDP send retCode = %s", retCode.c_str());
620 }
621 }
SocketHeartbeat() const622 void SpThreadSocket::SocketHeartbeat() const
623 {
624 Heartbeat &heartbeat = Heartbeat::GetInstance();
625 heartbeat.UpdatestartTime();
626 }
FetchCpuStats(SpServerSocket & spSocket,std::map<std::string,std::string> & data) const627 void SpThreadSocket::FetchCpuStats(SpServerSocket &spSocket, std::map<std::string, std::string>& data) const
628 {
629 std::string resultCpuFrequency = "";
630 std::string resultCpuUsage = "";
631 std::string resultCpu = "";
632 int cpuFrequencyNum = 0;
633 int cpuUsageNum = 0;
634 int cpuFlag = 1;
635 while (cpuFlag) {
636 resultCpuFrequency = "cpu" + std::to_string(cpuFrequencyNum) + "Frequency";
637 resultCpuUsage = "cpu" + std::to_string(cpuUsageNum) + "Usage";
638 auto iterCpuFrequency = data.find(resultCpuFrequency);
639 auto iterCpuUsage = data.find(resultCpuUsage);
640 if (iterCpuFrequency != data.end()) {
641 resultCpuFrequency += "||" + iterCpuFrequency->second;
642 resultCpu += "$$" + resultCpuFrequency;
643 cpuFrequencyNum++;
644 } else {
645 cpuFlag = 0;
646 }
647 if (iterCpuUsage != data.end()) {
648 resultCpuUsage += "||" + iterCpuUsage->second;
649 resultCpu += "$$" + resultCpuUsage;
650 cpuUsageNum++;
651 } else {
652 cpuFlag = 0;
653 }
654 }
655 spSocket.Sendto(resultCpu);
656 LOGD("UDP send resultCpu = %s", resultCpu.c_str());
657 }
HandleNullMsg(SpServerSocket & spSocket,SpProfiler * profiler,std::string & retCode,const std::string & recvBuf,std::unordered_map<MessageType,std::string>::const_iterator iterator)658 void SpThreadSocket::HandleNullMsg(SpServerSocket &spSocket, SpProfiler *profiler, std::string& retCode,
659 const std::string& recvBuf, std::unordered_map<MessageType, std::string>::const_iterator iterator)
660 {
661 if (iterator->first == MessageType::SET_PKG_NAME) {
662 isSetPid = false;
663 retCode = SplitMsg(recvBuf);
664 if (recvBuf.find(SMARTPERF) != std::string::npos && retCode.find(SMARTPERF) != std::string::npos) {
665 Dubai::dubaiPkgName = retCode;
666 LOGD("UDP send smartperf: (%s)", Dubai::dubaiPkgName.c_str());
667 } else {
668 if (retCode.find("$") != std::string::npos) {
669 g_pkgAndPid = retCode;
670 g_pkgName = SpGetPkg(g_pkgAndPid);
671 } else {
672 g_pkgName = retCode;
673 }
674 std::thread([this]() { this->ResetValue(g_pkgName); }).detach();
675 LOGD("HandleNullMsg pkgName: (%s)", g_pkgName.c_str());
676 }
677 spSocket.Sendto(retCode);
678 LOGD("UDP send PkgName = %s", retCode.c_str());
679 } else if (profiler == nullptr && (iterator->first == MessageType::GET_APP_TYPE)) {
680 retCode = SplitMsg(recvBuf);
681 std::thread([this, retCode]() { this->ResetValue(retCode); }).detach();
682 } else if (profiler == nullptr && (iterator->first == MessageType::GET_DAEMON_VERSION)) {
683 retCode = "Version: " + SPUtils::GetVersion();
684 spSocket.Sendto(retCode);
685 } else if (iterator->first == MessageType::CATCH_ONE_TRACE) {
686 bytrace.hiviewTrace = SplitMsg(recvBuf);
687 bytrace.CpTraceFile();
688 } else if (iterator->first == MessageType::CATCH_TRACE_FINISH) {
689 tracefilePath = "";
690 GetSocketPort(recvBuf);
691 ConnectAndSendFile(spSocket, tracefilePath);
692 } else if (iterator->first == MessageType::GET_CPU_NUM) {
693 retCode = SPUtils::GetCpuNum();
694 spSocket.Sendto(retCode);
695 LOGD("UDP send cpuNum = %s", retCode.c_str());
696 } else if (iterator->first == MessageType::BACK_TO_DESKTOP) {
697 BackDesktop();
698 } else {
699 HandleNullAddMsg(spSocket, profiler, retCode, recvBuf, iterator);
700 }
701 }
702
GetProcessIdByPkgName(std::unordered_map<MessageType,std::string>::const_iterator iterator)703 void SpThreadSocket::GetProcessIdByPkgName(std::unordered_map<MessageType, std::string>::const_iterator iterator)
704 {
705 if (iterator->first == MessageType::GET_FPS_AND_JITTERS || iterator->first == MessageType::GET_CUR_FPS ||
706 iterator->first == MessageType::GET_RAM_INFO) {
707 if (!SpProfilerFactory::editorFlag && isSetPid == false) {
708 FPS::GetInstance().isHistoryHap = true;
709 std::string pkgName = g_pkgName;
710 std::string pkgAndPid = g_pkgAndPid;
711 LOGD("SpProfilerFactory::g_pkgName(%s)", g_pkgName.c_str());
712 std::string processId = "";
713 std::string processIds = "";
714 FPS::GetInstance().isPreset = IsPreset(pkgAndPid);
715 if (FPS::GetInstance().isPreset) {
716 processId = SpGetPid(pkgAndPid);
717 } else {
718 OHOS::SmartPerf::StartUpDelay sp;
719 processId = sp.GetPidByPkg(pkgName, &processIds);
720 }
721 SpProfilerFactory::SetProfilerPidByPkg(processId, processIds);
722 SpProfilerFactory::SetProfilerPkg(pkgName);
723 isSetPid = true;
724 }
725 }
726 }
727
ResetValue(std::string retCode) const728 void SpThreadSocket::ResetValue(std::string retCode) const
729 {
730 FPS::GetInstance().isGameApp = SPUtils::GetIsGameApp(retCode);
731 RAM::GetInstance().SetHapFirstFlag();
732 }
HandleNullAddMsg(SpServerSocket & spSocket,SpProfiler * profiler,std::string & retCode,const std::string & recvBuf,std::unordered_map<MessageType,std::string>::const_iterator iterator)733 void SpThreadSocket::HandleNullAddMsg(SpServerSocket &spSocket, SpProfiler *profiler, std::string& retCode,
734 const std::string& recvBuf, std::unordered_map<MessageType, std::string>::const_iterator iterator)
735 {
736 Dubai &db = Dubai::GetInstance();
737 if (iterator->first == MessageType::START_DUBAI_DB) {
738 std::thread dStart([&db]() { db.CallBeginAndFinish(); });
739 dStart.detach();
740 } else if (iterator->first == MessageType::SET_DUBAI_DB) {
741 GetSocketPort(recvBuf);
742 db.CallBeginAndFinish();
743 FPS::GetInstance().isLowCurFps = false;
744 db.MoveDubaiDb(dubaiXpower);
745 ConnectAndSendFile(spSocket, dubaiFilePath);
746 retCode = "get_dubai_db";
747 LOGD("UDP send GetDubaiDb Message: (%s)", retCode.c_str());
748 spSocket.Sendto(retCode);
749 LOGD("UDP send DuBai get finish");
750 } else if (iterator->first == MessageType::CHECK_UDP_STATUS) {
751 retCode = "UDP status is normal";
752 spSocket.Sendto(retCode);
753 LOGD("UDP status is normal");
754 } else if (iterator->first == MessageType::SAVE_GPU_COUNTER) {
755 GetSocketPort(recvBuf);
756 std::unique_lock<std::mutex> lock(GpuCounter::GetInstance().GetGpuCounterLock());
757 ConnectAndSendFile(spSocket, gpuCounterfilePath + "/gpu_counter.csv");
758 } else if (iterator->first == MessageType::APP_STOP_COLLECT) {
759 if (taskMgr_ != nullptr) {
760 // UDP (device) 停止时,设置GPU_COUNTER保存路径
761 SPUtils::CreateDir(gpuCounterfilePath);
762 GpuCounter::GetInstance().SetSavePathDirectory(gpuCounterfilePath);
763 taskMgr_->SetHapFlag(false);
764 taskMgr_->Stop();
765 retCode = Hiperf::GetInstance().ReturnHiperfData();
766 spSocket.Sendto(retCode);
767 taskMgr_->WriteToCSV();
768 }
769 spTask.ClearStopFlag();
770 } else {
771 UdpStartMessProcess(spSocket, profiler, retCode, recvBuf, iterator);
772 }
773 }
774
UdpStartMessProcess(SpServerSocket & spSocket,SpProfiler * profiler,std::string & retCode,const std::string & recvBuf,std::unordered_map<MessageType,std::string>::const_iterator iterator)775 void SpThreadSocket::UdpStartMessProcess(SpServerSocket &spSocket, SpProfiler *profiler, std::string& retCode,
776 const std::string& recvBuf, std::unordered_map<MessageType, std::string>::const_iterator iterator)
777 {
778 if (iterator->first == MessageType::APP_START_COLLECT) {
779 if (taskMgr_ != nullptr) {
780 taskMgr_->AddTask(&SdkDataRecv::GetInstance(), false);
781 }
782 bytrace.ClearTraceFiles();
783 StartHapCollecting(spSocket);
784 } else if (iterator->first == MessageType::APP_RECEIVE_DATA_ON) {
785 if (taskMgr_ != nullptr) {
786 LOGD("Start to display data in real time");
787 taskMgr_->SetHapFlag(true);
788 taskMgr_->EnableIPCCallback();
789 }
790 } else if (iterator->first == MessageType::APP_RECEIVE_DATA_OFF) {
791 if (taskMgr_ != nullptr) {
792 LOGD("Real time data display ends");
793 taskMgr_->DisableIPCCallback();
794 }
795 } else if (iterator->first == MessageType::APP_PAUSE_COLLECT) {
796 if (taskMgr_ != nullptr) {
797 LOGD("Pause Collection");
798 SPUtils::CreateDir(gpuCounterfilePath);
799 GpuCounter::GetInstance().SetSavePathDirectory(gpuCounterfilePath);
800 GpuCounter::GetInstance().SetIsPause(true);
801 taskMgr_->Stop(true);
802 }
803 } else if (iterator->first == MessageType::APP_RESUME_COLLECT) {
804 LOGD("Resuming Collection");
805 StartHapCollecting(spSocket);
806 GpuCounter::GetInstance().SetIsPause(false);
807 } else if (iterator->first == MessageType::GET_INDEX_INFO) {
808 GetSocketPort(recvBuf);
809 ConnectAndSendFile(spSocket, indexFilePath);
810 } else {
811 retCode = iterator->second;
812 spSocket.Sendto(retCode);
813 LOGD("UDP sendData: (%s)", retCode.c_str());
814 }
815 }
SocketErrorTypeToString(SocketErrorType errorType) const816 std::string SpThreadSocket::SocketErrorTypeToString(SocketErrorType errorType) const
817 {
818 switch (errorType) {
819 case SocketErrorType::OK:
820 return "OK";
821 case SocketErrorType::TOKEN_CHECK_FAILED:
822 return "TOKEN_CHECK_FAILED";
823 case SocketErrorType::INIT_FAILED:
824 return "INIT_FAILED";
825 case SocketErrorType::START_FAILED:
826 return "START_FAILED";
827 case SocketErrorType::STOP_FAILED:
828 return "STOP_FAILED";
829 case SocketErrorType::START_RECORD_FAILED:
830 return "START_RECORD_FAILED";
831 case SocketErrorType::STOP_RECORD_FAILED:
832 return "STOP_RECORD_FAILED";
833 default:
834 return "UNKNOWN";
835 }
836 }
GetSocketPort(const std::string & buffer)837 void SpThreadSocket::GetSocketPort(const std::string& buffer)
838 {
839 if (buffer.find("::") != std::string::npos) {
840 std::string portStr = buffer.substr(buffer.find("::") + 2);
841 std::string fileName = "";
842 if (portStr.find(":::") != std::string::npos) {
843 portStr = portStr.substr(0, portStr.find(":::"));
844 }
845
846 if (portStr.find("$") != std::string::npos) {
847 fileName = portStr.substr(portStr.find("$") + 1);
848 portStr = portStr.substr(0, portStr.find("$"));
849 tracefilePath = traceOriginPath + fileName;
850 }
851
852 int port = SPUtilesTye::StringToSometype<int>(portStr);
853 if (port <= 0) {
854 WLOGE("Invalid port number: %d", port);
855 sendFileSocketPort = -1;
856 } else {
857 WLOGI("Get File log UDP message received, port is %d", port);
858 sendFileSocket = -1;
859 sendFileSocketPort = port;
860 }
861 } else {
862 WLOGE("Get File log UDP message received, but port is not found");
863 sendFileSocketPort = -1;
864 }
865 }
SpGetPkg(const std::string & spMsg) const866 std::string SpThreadSocket::SpGetPkg(const std::string &spMsg) const
867 {
868 if (spMsg.empty()) {
869 return spMsg;
870 }
871 size_t pos = spMsg.find("$");
872 if (pos != std::string::npos) {
873 std::vector<std::string> sps;
874 SPUtils::StrSplit(spMsg, "$", sps);
875 if (sps.size() > 1) {
876 return sps[0];
877 } else {
878 return spMsg;
879 }
880 } else {
881 return spMsg;
882 }
883 }
884
SpGetPid(const std::string & spMsg) const885 std::string SpThreadSocket::SpGetPid(const std::string &spMsg) const
886 {
887 if (spMsg.empty()) {
888 LOGE("spMsg is null");
889 return spMsg;
890 }
891 size_t pos = spMsg.find("$");
892 if (pos != std::string::npos) {
893 std::vector<std::string> sps;
894 SPUtils::StrSplit(spMsg, "$", sps);
895 if (sps.size() > 1) {
896 return sps[1];
897 } else {
898 LOGE("SpGetPid sps size is zreo");
899 return "";
900 }
901 } else {
902 return "";
903 }
904 }
905
IsPreset(const std::string & spMsg) const906 bool SpThreadSocket::IsPreset(const std::string &spMsg) const
907 {
908 return spMsg.find("$") != std::string::npos;
909 }
910
SetToken(const std::string & token)911 void SpThreadSocket::SetToken(const std::string& token)
912 {
913 checkToken = token;
914 }
915
GetToken() const916 std::string SpThreadSocket::GetToken() const
917 {
918 return checkToken;
919 }
920
SetNeedUdpToken(bool isNeed)921 void SpThreadSocket::SetNeedUdpToken(bool isNeed)
922 {
923 isNeedUdpToken = isNeed;
924 }
925
StartHapCollecting(SpServerSocket & spSocket)926 void SpThreadSocket::StartHapCollecting(SpServerSocket &spSocket)
927 {
928 LOGD("UDP START Task starting...");
929 RAM &ram = RAM::GetInstance();
930 ram.SetFirstFlag();
931 if (udpStartCollect.joinable()) {
932 udpStartCollect.join();
933 }
934 udpStartCollect = std::thread([this]() {
935 if (taskMgr_ == nullptr) {
936 return;
937 }
938 taskMgr_->Start();
939 taskMgr_->SetRecordState(true);
940 taskMgr_->Wait();
941 LOGD("Data collecting thread exiting.");
942 });
943 return;
944 }
945 }
946 }