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