1 /*
2 * Copyright (c) 2023 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 "benchmarks/file_utils.h"
17 #include <fstream>
18 #include <filesystem>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include "platform/common/rs_log.h"
22 #include "rs_trace.h"
23
24 namespace OHOS {
25 namespace Rosen {
26 namespace Benchmarks {
IsValidFile(const std::string & realPathStr,const std::string & validFile)27 bool IsValidFile(const std::string& realPathStr, const std::string& validFile)
28 {
29 return realPathStr.find(validFile) == 0;
30 }
31
GetRealAndValidPath(const std::string & filePath)32 std::string GetRealAndValidPath(const std::string& filePath)
33 {
34 std::string realPathStr = std::filesystem::path(filePath).lexically_normal().string();
35 if (IsValidFile(realPathStr)) {
36 return realPathStr;
37 } else {
38 RS_LOGE("FileUtils: The file path is not valid!");
39 return "";
40 }
41 }
42
CreateFile(const std::string & filePath)43 bool CreateFile(const std::string& filePath)
44 {
45 std::string realPath = GetRealAndValidPath(filePath);
46 if (realPath.empty()) {
47 return false;
48 }
49 std::ofstream outFile(realPath);
50 if (!outFile.is_open()) {
51 RS_LOGE("FileUtils: file %{public}s open failed!", realPath.c_str());
52 return false;
53 }
54 outFile.clear();
55 outFile.close();
56 return true;
57 }
58
WriteToFile(uintptr_t data,size_t size,const std::string & filePath)59 bool WriteToFile(uintptr_t data, size_t size, const std::string& filePath)
60 {
61 if (!CreateFile(filePath)) {
62 return false;
63 }
64 if (filePath.empty()) {
65 return false;
66 }
67 int fd = open(filePath.c_str(), O_RDWR | O_CREAT, static_cast<mode_t>(0600));
68 if (fd < 0) {
69 RS_LOGE("FileUtils: %{public}s failed. file: %{public}s, fd = %{public}d", __func__, filePath.c_str(), fd);
70 return false;
71 }
72 ssize_t nwrite = write(fd, reinterpret_cast<uint8_t *>(data), size);
73 if (nwrite < 0) {
74 RS_LOGE("FileUtils: %{public}s failed to persist data, size = %{public}zu, fd = %{public}d",
75 __func__, size, fd);
76 }
77 close(fd);
78 return true;
79 }
80
WriteStringToFile(int fd,const std::string & str)81 bool WriteStringToFile(int fd, const std::string& str)
82 {
83 const char* p = str.data();
84 ssize_t remaining = static_cast<ssize_t>(str.size());
85 while (remaining > 0) {
86 ssize_t n = write(fd, p, remaining);
87 if (n == -1) {
88 return false;
89 }
90 p += n;
91 remaining -= n;
92 }
93 p = nullptr;
94 return true;
95 }
96
WriteStringToFile(const std::string & str,const std::string & filePath)97 bool WriteStringToFile(const std::string& str, const std::string& filePath)
98 {
99 if (!CreateFile(filePath)) {
100 return false;
101 }
102 if (filePath.empty()) {
103 return false;
104 }
105 int fd = open(filePath.c_str(), O_RDWR | O_CREAT, static_cast<mode_t>(0600));
106 if (fd < 0) {
107 RS_LOGE("FileUtils: %{public}s failed. file: %{public}s, fd = %{public}d", __func__, filePath.c_str(), fd);
108 return false;
109 }
110 bool result = WriteStringToFile(fd, str);
111 close(fd);
112 return result;
113 }
114
WriteMessageParcelToFile(std::shared_ptr<MessageParcel> messageParcel,const std::string & opsDescription,int frameNum,const std::string & fileDir)115 bool WriteMessageParcelToFile(std::shared_ptr<MessageParcel> messageParcel, const std::string& opsDescription,
116 int frameNum, const std::string& fileDir)
117 {
118 // file name
119 std::string drawCmdListFile = fileDir + "/frame" + std::to_string(frameNum) + ".drawing";
120 std::string opsFile = fileDir + "/ops_frame" + std::to_string(frameNum) + ".txt";
121 // get data
122 size_t sz = messageParcel->GetDataSize();
123 #ifndef USE_ROSEN_DRAWING
124 uintptr_t buf = messageParcel->GetData();
125 #else
126 auto buf = reinterpret_cast<uintptr_t>(messageParcel->GetData());
127 #endif
128 std::string line = "RSRecordingThread::FinishRecordingOneFrame curDumpFrame = " +
129 std::to_string(frameNum) + ", size = " + std::to_string(sz);
130 RS_LOGD("%{public}s", line.c_str());
131 RS_TRACE_NAME(line);
132
133 return OHOS::Rosen::Benchmarks::WriteToFile(buf, sz, drawCmdListFile) &&
134 OHOS::Rosen::Benchmarks::WriteStringToFile(opsDescription, opsFile);
135 }
136 }
137 } // namespace Rosen
138 } // namespace OHOS