1 /*
2 * Copyright (c) 2020-2022 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 "compare_tools.h"
17 #include <cstring>
18 #include "common/screen.h"
19 #include "dock/screen_device_proxy.h"
20 #include "draw/draw_utils.h"
21 #include "gfx_utils/file.h"
22 #include "gfx_utils/graphic_log.h"
23 #include "gfx_utils/graphic_math.h"
24 #include "graphic_config.h"
25 #include "securec.h"
26
27 #ifdef _WIN32
28 #define STR(STRING) #STRING
29 #define STRPATH(STRING) STR(STRING)
30 #endif
31
32 namespace OHOS {
33 bool CompareTools::enableLog_ = false;
34 char* CompareTools::logPath_ = nullptr;
35
WaitSuspend(const uint16_t waitTime)36 void CompareTools::WaitSuspend(const uint16_t waitTime)
37 {
38 uint16_t sleepTime = waitTime == 0 ? DEFAULT_WAIT_TIME_MS : waitTime;
39 #ifdef _WIN32
40 Sleep(sleepTime);
41 #else
42 usleep(1000 * sleepTime); // 1000: us to ms
43 #endif // _WIN32
44 }
45
StrnCatPath(char * filePath,size_t pathMax,const char * fileName,size_t count)46 bool CompareTools::StrnCatPath(char* filePath, size_t pathMax, const char* fileName, size_t count)
47 {
48 if ((filePath == nullptr) || (pathMax > DEFAULT_FILE_NAME_MAX_LENGTH)) {
49 return false;
50 }
51 #ifdef _WIN32
52 char dest[DEFAULT_FILE_NAME_MAX_LENGTH] = STRPATH(AUTO_TEST_RESOURCE_PATH);
53 #else
54 char dest[DEFAULT_FILE_NAME_MAX_LENGTH] = AUTO_TEST_RESOURCE_PATH;
55 #endif // _WIN32
56 if (strncat_s(dest, DEFAULT_FILE_NAME_MAX_LENGTH, fileName, count) != EOK) {
57 return false;
58 }
59 if (memcpy_s(static_cast<void *>(filePath), pathMax, dest, DEFAULT_FILE_NAME_MAX_LENGTH) != EOK) {
60 return false;
61 }
62 return true;
63 }
64
CompareByBit(uint32_t fd)65 bool CompareTools::CompareByBit(uint32_t fd)
66 {
67 ImageInfo imageBit;
68 if (!(Screen::GetInstance().GetCurrentScreenBitmap(imageBit))) {
69 return false;
70 }
71 struct BitmapInfoHeader bitmapInfo = {0};
72 lseek(fd, sizeof(uint16_t), SEEK_SET);
73 if (read(fd, &bitmapInfo, sizeof(bitmapInfo)) < 0) {
74 ImageCacheFree(imageBit);
75 return false;
76 }
77 if (bitmapInfo.biSizeImage != imageBit.dataSize) {
78 ImageCacheFree(imageBit);
79 return false;
80 }
81 bool flag = true;
82 uint32_t buffSize = bitmapInfo.biSizeImage / MATH_ABS(bitmapInfo.biHeight);
83 auto buff = new uint8_t[buffSize];
84 for (uint32_t i = 0; i < MATH_ABS(bitmapInfo.biHeight); i++) {
85 if (flag && (memset_s(buff, buffSize, 0, buffSize) != EOK)) {
86 flag = false;
87 break;
88 }
89 int32_t ret = read(fd, buff, buffSize);
90 if (ret < 0) {
91 flag = false;
92 break;
93 }
94 for (uint32_t j = 0; j < ret; j++) {
95 if (buff[j] != imageBit.data[i * buffSize + j]) {
96 flag = false;
97 break;
98 }
99 }
100 }
101 ImageCacheFree(imageBit);
102 delete [] buff;
103 buff = nullptr;
104 return flag;
105 }
106
CompareByBitmap(const BitmapInfoHeader bitmapInfoBase,const BitmapInfoHeader bitmapInfoRun,uint32_t fdBase,uint32_t fdRun)107 bool CompareTools::CompareByBitmap(const BitmapInfoHeader bitmapInfoBase,
108 const BitmapInfoHeader bitmapInfoRun, uint32_t fdBase, uint32_t fdRun)
109 {
110 bool flag = true;
111 uint32_t buffSizeBase = bitmapInfoBase.biSizeImage / MATH_ABS(bitmapInfoBase.biHeight);
112 auto buffBase = new uint8_t[buffSizeBase];
113
114 uint32_t buffSizeRun = bitmapInfoRun.biSizeImage / MATH_ABS(bitmapInfoRun.biHeight);
115 auto buffRun = new uint8_t[buffSizeRun];
116
117 for (uint32_t i = 0; i < MATH_ABS(bitmapInfoBase.biHeight); i++) {
118 if (flag && (memset_s(buffBase, buffSizeBase, 0, buffSizeBase) != EOK)) {
119 flag = false;
120 break;
121 }
122 if (flag && (memset_s(buffRun, buffSizeRun, 0, buffSizeRun) != EOK)) {
123 flag = false;
124 break;
125 }
126 int32_t retBase = read(fdBase, buffBase, buffSizeBase);
127 if (retBase < 0) {
128 flag = false;
129 break;
130 }
131 int32_t retRun = read(fdRun, buffRun, buffSizeBase);
132 if (retRun < 0) {
133 flag = false;
134 break;
135 }
136 if (retBase != retRun) {
137 flag = false;
138 break;
139 }
140
141 for (uint32_t j = 0; j < retBase; j++) {
142 if (buffBase[j] != buffRun[j]) {
143 flag = false;
144 break;
145 }
146 }
147 }
148
149 delete [] buffBase;
150 buffBase = nullptr;
151 delete [] buffRun;
152 buffRun = nullptr;
153
154 return flag;
155 }
156
157
CompareFile(const char * fileBasePath,const char * fileRunPath)158 bool CompareTools::CompareFile(const char* fileBasePath, const char* fileRunPath)
159 {
160 if (fileBasePath == nullptr || fileRunPath == nullptr) {
161 return false;
162 }
163 #ifdef _WIN32
164 uint32_t fdBase = open(fileBasePath, O_RDONLY | O_BINARY);
165 uint32_t fdRun = open(fileRunPath, O_RDONLY | O_BINARY);
166 #else
167 uint32_t fdBase = open(fileBasePath, O_RDONLY);
168 uint32_t fdRun = open(fileRunPath, O_RDONLY);
169 #endif
170 struct BitmapInfoHeader bitmapInfoBase = {0};
171 lseek(fdBase, sizeof(uint16_t), SEEK_SET);
172 if (read(fdBase, &bitmapInfoBase, sizeof(bitmapInfoBase)) < 0) {
173 close(fdBase);
174 close(fdRun);
175 return false;
176 }
177
178 struct BitmapInfoHeader bitmapInfoRun = {0};
179 lseek(fdRun, sizeof(uint16_t), SEEK_SET);
180 if (read(fdRun, &bitmapInfoRun, sizeof(bitmapInfoRun)) < 0) {
181 close(fdBase);
182 close(fdRun);
183 return false;
184 }
185
186 if (bitmapInfoBase.biSizeImage != bitmapInfoRun.biSizeImage) {
187 close(fdBase);
188 close(fdRun);
189 return false;
190 }
191
192 if (!CompareByBitmap(bitmapInfoBase, bitmapInfoRun, fdBase, fdRun)) {
193 close(fdBase);
194 close(fdRun);
195 return false;
196 }
197
198 close(fdBase);
199 close(fdRun);
200 return true;
201 }
202
CompareFile(const char * filePath,size_t length)203 bool CompareTools::CompareFile(const char* filePath, size_t length)
204 {
205 if ((filePath == nullptr) || (length > DEFAULT_FILE_NAME_MAX_LENGTH)) {
206 return false;
207 }
208 #ifdef _WIN32
209 uint32_t fd = open(filePath, O_RDONLY | O_BINARY);
210 #else
211 uint32_t fd = open(filePath, O_RDONLY);
212 #endif
213 if (fd == -1) {
214 return false;
215 }
216 bool flag = CompareByBit(fd);
217 close(fd);
218 if (flag) {
219 GRAPHIC_LOGI("[COMPARE_SUCCESS]:fileName=%s", filePath);
220 if (enableLog_) {
221 char logInfo[DEFAULT_FILE_NAME_MAX_LENGTH] = {0};
222 if (sprintf_s(logInfo, sizeof(logInfo), "[COMPARE_SUCCESS]:fileName=%s\n", filePath) < 0) {
223 return false;
224 }
225 SaveLog(logInfo, strlen(logInfo));
226 }
227 } else {
228 GRAPHIC_LOGI("[COMPARE_FAILURE]:fileName=%s", filePath);
229 if (enableLog_) {
230 char logInfo[DEFAULT_FILE_NAME_MAX_LENGTH] = {0};
231 if (sprintf_s(logInfo, sizeof(logInfo), "[COMPARE_FAILURE]:fileName=%s\n", filePath) < 0) {
232 return false;
233 }
234 SaveLog(logInfo, strlen(logInfo));
235 }
236 }
237 return flag;
238 }
239
SaveByBit(uint32_t fd)240 bool CompareTools::SaveByBit(uint32_t fd)
241 {
242 ImageInfo imageBit;
243 if (!(Screen::GetInstance().GetCurrentScreenBitmap(imageBit))) {
244 return false;
245 }
246 bool flag = false;
247 uint8_t sizeByColorMode = DrawUtils::GetByteSizeByColorMode(ScreenDeviceProxy::GetInstance()->GetBufferMode());
248 uint16_t bfType = 0x4D42;
249 struct BitmapInfoHeader bitmapInfo = {0};
250 bitmapInfo.bfSize = imageBit.dataSize + BITMAP_HEADER_SIZE;
251 bitmapInfo.bfOffBits = BITMAP_HEADER_SIZE;
252 bitmapInfo.biSize = 40; // 40: bitmap information header size
253 bitmapInfo.biWidth = imageBit.header.width;
254 bitmapInfo.biHeight = -imageBit.header.height;
255 bitmapInfo.biPlanes = 1;
256 bitmapInfo.biBitCount = sizeByColorMode * 8; // 8: uint8_t bit
257 bitmapInfo.biSizeImage = imageBit.dataSize;
258 if (write(fd, &bfType, sizeof(bfType)) > 0) {
259 if (write(fd, &bitmapInfo, sizeof(bitmapInfo)) > 0) {
260 if (write(fd, imageBit.data, imageBit.dataSize) > 0) {
261 flag = true;
262 }
263 }
264 }
265 ImageCacheFree(imageBit);
266 return flag;
267 }
268
SaveResultLog(const char * filePath,const char * buff,size_t bufSize)269 void CompareTools::SaveResultLog(const char* filePath, const char* buff, size_t bufSize)
270 {
271 if (filePath == nullptr || buff == nullptr || bufSize <= 0) {
272 return;
273 }
274
275 SaveLog(buff, bufSize, filePath);
276 }
277
SaveFile(const char * filePath,size_t length)278 bool CompareTools::SaveFile(const char* filePath, size_t length)
279 {
280 if ((filePath == nullptr) || (length > DEFAULT_FILE_NAME_MAX_LENGTH)) {
281 return false;
282 }
283 #ifdef _WIN32
284 uint32_t fd = open(filePath, O_WRONLY | O_CREAT | O_BINARY, DEFAULT_FILE_PERMISSION);
285 #else
286 uint32_t fd = open(filePath, O_WRONLY | O_CREAT, DEFAULT_FILE_PERMISSION);
287 #endif
288 if (fd == -1) {
289 return false;
290 }
291 bool flag = SaveByBit(fd);
292 close(fd);
293 return flag;
294 }
295
CheckFileExist(const char * filePath,size_t length)296 bool CompareTools::CheckFileExist(const char* filePath, size_t length)
297 {
298 if ((filePath == nullptr) || (length > DEFAULT_FILE_NAME_MAX_LENGTH)) {
299 return false;
300 }
301 uint32_t fd = open(filePath, O_RDONLY);
302 if (fd == -1) {
303 return false;
304 }
305 close(fd);
306 return true;
307 }
308
SetLogPath(const char * filePath,size_t length)309 void CompareTools::SetLogPath(const char* filePath, size_t length)
310 {
311 if (logPath_ == nullptr) {
312 logPath_ = new char[length];
313 if (logPath_ == nullptr) {
314 return;
315 }
316 if (memcpy_s(logPath_, length, filePath, length) != EOK) {
317 GRAPHIC_LOGE("memcpy filepath failed");
318 return;
319 }
320 enableLog_ = true;
321 }
322 }
323
UnsetLogPath()324 void CompareTools::UnsetLogPath()
325 {
326 if (logPath_ != nullptr) {
327 delete[] logPath_;
328 logPath_ = nullptr;
329 enableLog_ = false;
330 }
331 }
332
SaveLog(const char * buff,size_t bufSize,const char * filePath)333 bool CompareTools::SaveLog(const char* buff, size_t bufSize, const char* filePath)
334 {
335 if (buff == nullptr) {
336 return false;
337 }
338
339 const char* useLogPath = filePath == nullptr ? logPath_ : filePath;
340 if (useLogPath == nullptr) {
341 return false;
342 }
343
344 uint32_t logFd = open(useLogPath, O_WRONLY | O_CREAT | O_APPEND, DEFAULT_FILE_PERMISSION);
345 if (logFd == -1) {
346 GRAPHIC_LOGE("open log failed");
347 return false;
348 }
349 if (write(logFd, buff, bufSize) < 0) {
350 close(logFd);
351 GRAPHIC_LOGE("write log failed");
352 return false;
353 }
354 close(logFd);
355 return true;
356 }
357 } // namespace OHOS
358