• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "util.h"
17 
18 #include <event_handler.h>
19 #include <fstream>
20 #include <securec.h>
21 #include <sstream>
22 #include <parameters.h>
23 
24 namespace OHOS {
25 
PostTask(std::function<void ()> func,uint32_t delayTime)26 void PostTask(std::function<void()> func, uint32_t delayTime)
27 {
28     auto handler = AppExecFwk::EventHandler::Current();
29     if (handler) {
30         handler->PostTask(func, delayTime);
31     }
32 }
33 
IsFileExisted(const std::string & filePath)34 bool IsFileExisted(const std::string& filePath)
35 {
36     if (filePath.empty()) {
37         LOGE("check filepath is empty");
38         return false;
39     }
40     char newpath[PATH_MAX + 1] = { 0x00 };
41     if (strlen(filePath.c_str()) > PATH_MAX || realpath(filePath.c_str(), newpath) == nullptr) {
42         LOGE("check filepath fail! %{public}s %{public}d %{public}s", filePath.c_str(), errno, ::strerror(errno));
43         return false;
44     }
45     struct stat info = {0};
46     if (stat(newpath, &info) != 0) {
47         LOGE("stat filepath fail! %{public}s %{public}d %{public}s", filePath.c_str(), errno, ::strerror(errno));
48         return false;
49     }
50     return true;
51 }
52 
ParseBootConfig(const std::string & path,int32_t & duration,bool & isCompatible,bool & isMultiDisplay,std::vector<BootAnimationConfig> & configs)53 bool ParseBootConfig(const std::string& path, int32_t& duration, bool& isCompatible, bool& isMultiDisplay,
54     std::vector<BootAnimationConfig>& configs)
55 {
56     cJSON* overallData = ParseFileConfig(path);
57     if (overallData == nullptr) {
58         LOGE("can not parse config to json");
59         return false;
60     }
61     cJSON_bool isNewConfig = cJSON_HasObjectItem(overallData, "screen_config");
62     if (!isNewConfig) {
63         isCompatible = true;
64         ParseOldConfigFile(overallData, configs);
65     } else {
66         ParseNewConfigFile(overallData, isMultiDisplay, configs);
67     }
68     ParseBootDuration(overallData, duration);
69     cJSON_Delete(overallData);
70     return true;
71 }
72 
ParseOldConfigFile(cJSON * data,std::vector<BootAnimationConfig> & configs)73 void ParseOldConfigFile(cJSON* data, std::vector<BootAnimationConfig>& configs)
74 {
75     LOGD("ParseOldConfigFile");
76     BootAnimationConfig config;
77     cJSON* custPicPath = cJSON_GetObjectItem(data, "cust.bootanimation.pics");
78     if (custPicPath != nullptr && cJSON_IsString(custPicPath)) {
79         config.picZipPath = custPicPath->valuestring;
80     }
81     cJSON* custSoundPath = cJSON_GetObjectItem(data, "cust.bootanimation.sounds");
82     if (custSoundPath != nullptr && cJSON_IsString(custSoundPath)) {
83         config.soundPath = custSoundPath->valuestring;
84     }
85     cJSON* custVideoDefaultPath = cJSON_GetObjectItem(data, "cust.bootanimation.video");
86     if (custVideoDefaultPath != nullptr && cJSON_IsString(custVideoDefaultPath)) {
87         config.videoDefaultPath = custVideoDefaultPath->valuestring;
88     }
89     cJSON* custVideoExtraPath = cJSON_GetObjectItem(data, "cust.bootanimation.video.extra");
90     if (custVideoExtraPath != nullptr && cJSON_IsString(custVideoExtraPath)) {
91         config.videoExtraPath = custVideoExtraPath->valuestring;
92     }
93     cJSON* rotateScreenJson = cJSON_GetObjectItem(data, "cust.bootanimation.rotate.screenid");
94     if (rotateScreenJson != nullptr && cJSON_IsString(rotateScreenJson)) {
95         config.rotateScreenId = std::atoi(rotateScreenJson->valuestring);
96         LOGI("cust rotateScreenId: %{public}d", config.rotateScreenId);
97     }
98     cJSON* rotateDegreeJson = cJSON_GetObjectItem(data, "cust.bootanimation.rotate.degree");
99     if (rotateDegreeJson != nullptr && cJSON_IsString(rotateDegreeJson)) {
100         config.rotateDegree = std::atoi(rotateDegreeJson->valuestring);
101         LOGI("cust rotateDegree: %{public}d", config.rotateDegree);
102     }
103     cJSON* extraVideoPath = cJSON_GetObjectItem(data, "cust.bootanimation.video_extensions");
104     if (extraVideoPath != nullptr && cJSON_IsObject(extraVideoPath)) {
105         ParseVideoExtraPath(extraVideoPath, config);
106     }
107     configs.emplace_back(config);
108 }
109 
ParseNewConfigFile(cJSON * data,bool & isMultiDisplay,std::vector<BootAnimationConfig> & configs)110 void ParseNewConfigFile(cJSON* data, bool& isMultiDisplay, std::vector<BootAnimationConfig>& configs)
111 {
112     LOGD("ParseNewConfigFile");
113     cJSON* isSupport = cJSON_GetObjectItem(data, "cust.bootanimation.multi_display");
114     if (isSupport != nullptr && cJSON_IsBool(isSupport)) {
115         if (cJSON_IsTrue(isSupport)) {
116             isMultiDisplay = true;
117         }
118     }
119     LOGI("isMultiDisplay: %{public}d", isMultiDisplay);
120 
121     cJSON* screens = cJSON_GetObjectItem(data, "screen_config");
122     if (screens != nullptr) {
123         BootAnimationConfig config;
124         cJSON* item = screens->child;
125         while (item != nullptr) {
126             cJSON* screenIdJson = cJSON_GetObjectItem(item, "cust.bootanimation.screen_id");
127             if (screenIdJson != nullptr && cJSON_IsString(screenIdJson)) {
128                 config.screenId = std::strtoul(screenIdJson->valuestring, nullptr, 0);
129                 LOGI("screenId: " BPUBU64 "", config.screenId);
130             }
131             cJSON* custPicPath = cJSON_GetObjectItem(item, "cust.bootanimation.pics");
132             if (custPicPath != nullptr && cJSON_IsString(custPicPath)) {
133                 config.picZipPath = custPicPath->valuestring;
134             }
135             cJSON* custSoundPath = cJSON_GetObjectItem(item, "cust.bootanimation.sounds");
136             if (custSoundPath != nullptr && cJSON_IsString(custSoundPath)) {
137                 config.soundPath = custSoundPath->valuestring;
138             }
139             cJSON* custVideoDefaultPath = cJSON_GetObjectItem(item, "cust.bootanimation.video_default");
140             if (custVideoDefaultPath != nullptr && cJSON_IsString(custVideoDefaultPath)) {
141                 config.videoDefaultPath = custVideoDefaultPath->valuestring;
142             }
143             cJSON* rotateDegreeJson = cJSON_GetObjectItem(item, "cust.bootanimation.rotate_degree");
144             if (rotateDegreeJson != nullptr && cJSON_IsString(rotateDegreeJson)) {
145                 config.rotateDegree = std::atoi(rotateDegreeJson->valuestring);
146                 LOGI("cust rotateDegree: %{public}d", config.rotateDegree);
147             }
148             cJSON* extraVideoPath = cJSON_GetObjectItem(item, "cust.bootanimation.video_extensions");
149             if (extraVideoPath != nullptr && cJSON_IsObject(extraVideoPath)) {
150                 ParseVideoExtraPath(extraVideoPath, config);
151             }
152             configs.emplace_back(config);
153             item = item->next;
154         }
155     }
156 }
157 
ParseProgressData(cJSON * data,std::map<int32_t,BootAnimationProgressConfig> & configs)158 void ParseProgressData(cJSON* data, std::map<int32_t, BootAnimationProgressConfig>& configs)
159 {
160     LOGI("ParseProgressData");
161     cJSON* progressConfigs = cJSON_GetObjectItem(data, "progress_config");
162     if (progressConfigs != nullptr) {
163         BootAnimationProgressConfig config;
164         cJSON* item = progressConfigs->child;
165         while (item != nullptr) {
166             cJSON* progressScreenIdJson = cJSON_GetObjectItem(item, "cust.bootanimation.progress_screen_id");
167             if (progressScreenIdJson != nullptr && cJSON_IsString(progressScreenIdJson)) {
168                 config.progressScreenId = std::atoi(progressScreenIdJson->valuestring);
169             }
170             cJSON* progressHeightJson = cJSON_GetObjectItem(item, "cust.bootanimation.progress_height");
171             if (progressHeightJson != nullptr && cJSON_IsString(progressHeightJson)) {
172                 config.progressHeight = std::atoi(progressHeightJson->valuestring);
173             }
174             cJSON* progressFrameHeightJson = cJSON_GetObjectItem(item, "cust.bootanimation.progress_frame_height");
175             if (progressFrameHeightJson != nullptr && cJSON_IsString(progressFrameHeightJson)) {
176                 config.progressFrameHeight = std::atoi(progressFrameHeightJson->valuestring);
177             }
178             cJSON* progressOffsetJson = cJSON_GetObjectItem(item, "cust.bootanimation.progress_x_offset");
179             if (progressOffsetJson != nullptr && cJSON_IsString(progressOffsetJson)) {
180                 config.progressOffset = std::atoi(progressOffsetJson->valuestring);
181             }
182             cJSON* progressFontSizeJson = cJSON_GetObjectItem(item, "cust.bootanimation.progress_font_size");
183             if (progressFontSizeJson != nullptr && cJSON_IsString(progressFontSizeJson)) {
184                 config.progressFontSize = std::atoi(progressFontSizeJson->valuestring);
185             }
186             cJSON* progressRadiusSizeJson = cJSON_GetObjectItem(item, "cust.bootanimation.progress_radius_size");
187             if (progressRadiusSizeJson != nullptr && cJSON_IsString(progressRadiusSizeJson)) {
188                 config.progressRadiusSize = std::atoi(progressRadiusSizeJson->valuestring);
189             }
190             cJSON* progressDegreeJson = cJSON_GetObjectItem(item, "cust.bootanimation.progress_degree");
191             if (progressDegreeJson != nullptr && cJSON_IsString(progressDegreeJson)) {
192                 config.progressDegree = std::atoi(progressDegreeJson->valuestring);
193             }
194             configs.emplace(config.progressScreenId, config);
195             item = item->next;
196         }
197     }
198 }
199 
ParseProgressConfig(const std::string & path,std::map<int32_t,BootAnimationProgressConfig> & configs)200 void ParseProgressConfig(const std::string& path, std::map<int32_t, BootAnimationProgressConfig>& configs)
201 {
202     LOGI("ParseProgressConfig");
203     cJSON* overallData = ParseFileConfig(path);
204     if (overallData == nullptr) {
205         LOGE("can not parse config to json");
206         return;
207     }
208     cJSON_bool hasProgressConfig = cJSON_HasObjectItem(overallData, "progress_config");
209     if (!hasProgressConfig) {
210         LOGE("has no progress config");
211         cJSON_Delete(overallData);
212         return;
213     }
214     ParseProgressData(overallData, configs);
215     cJSON_Delete(overallData);
216 }
217 
ParseFileConfig(const std::string & path)218 cJSON* ParseFileConfig(const std::string& path)
219 {
220     char newpath[PATH_MAX + 1] = { 0x00 };
221     if (strlen(path.c_str()) > PATH_MAX || realpath(path.c_str(), newpath) == nullptr) {
222         LOGE("check config path fail! %{public}s %{public}d %{public}s", path.c_str(), errno, ::strerror(errno));
223         return nullptr;
224     }
225 
226     std::ifstream configFile;
227     configFile.open(newpath);
228     std::stringstream JFilterParamsStream;
229     JFilterParamsStream << configFile.rdbuf();
230     configFile.close();
231     std::string JParamsString = JFilterParamsStream.str();
232 
233     return cJSON_Parse(JParamsString.c_str());
234 }
235 
ParseVideoExtraPath(cJSON * data,BootAnimationConfig & config)236 void ParseVideoExtraPath(cJSON* data, BootAnimationConfig& config)
237 {
238     int size = cJSON_GetArraySize(data);
239     for (int index = 0; index < size; index++) {
240         cJSON* extraPath = cJSON_GetArrayItem(data, index);
241         if (extraPath != nullptr && extraPath->string != nullptr && extraPath->valuestring != nullptr
242             && strlen(extraPath->string) != 0) {
243             config.videoExtPath.emplace(extraPath->string, extraPath->valuestring);
244         }
245     }
246 }
247 
ParseBootDuration(cJSON * data,int32_t & duration)248 void ParseBootDuration(cJSON* data, int32_t& duration)
249 {
250     cJSON* durationJson = cJSON_GetObjectItem(data, "cust.bootanimation.duration");
251     if (durationJson != nullptr && cJSON_IsString(durationJson)) {
252         duration = std::atoi(durationJson->valuestring);
253         LOGI("cust duration: %{public}d", duration);
254     }
255 }
256 
ReadZipFile(const std::string & srcFilePath,ImageStructVec & imgVec,FrameRateConfig & frameConfig)257 bool ReadZipFile(const std::string& srcFilePath, ImageStructVec& imgVec, FrameRateConfig& frameConfig)
258 {
259     unzFile zipFile = unzOpen2(srcFilePath.c_str(), nullptr);
260     if (zipFile == nullptr) {
261         LOGE("Open zipFile fail: %{public}s", srcFilePath.c_str());
262         return false;
263     }
264 
265     unz_global_info globalInfo;
266     if (unzGetGlobalInfo(zipFile, &globalInfo) != UNZ_OK) {
267         LOGE("Get ZipGlobalInfo fail");
268         return CloseZipFile(zipFile, false);
269     }
270 
271     LOGD("read zip file num: %{public}ld", globalInfo.number_entry);
272     for (unsigned long i = 0; i < globalInfo.number_entry; ++i) {
273         unz_file_info fileInfo;
274         char filename[MAX_FILE_NAME] = {0};
275         if (unzGetCurrentFileInfo(zipFile, &fileInfo, filename, MAX_FILE_NAME, nullptr, 0, nullptr, 0) != UNZ_OK) {
276             return CloseZipFile(zipFile, false);
277         }
278         size_t length = strlen(filename);
279         if (length > MAX_FILE_NAME || length == 0) {
280             return CloseZipFile(zipFile, false);
281         }
282         if (filename[length - 1] != '/') {
283             if (unzOpenCurrentFile(zipFile) != UNZ_OK) {
284                 return CloseZipFile(zipFile, false);
285             }
286             std::string name = std::string(filename);
287             size_t npos = name.find_last_of("//");
288             if (npos != std::string::npos) {
289                 name = name.substr(npos + 1, name.length());
290             }
291             if (!ReadImageFile(zipFile, name, imgVec, frameConfig, fileInfo.uncompressed_size)) {
292                 LOGE("read zip deal single file failed");
293                 unzCloseCurrentFile(zipFile);
294                 return CloseZipFile(zipFile, false);
295             }
296             unzCloseCurrentFile(zipFile);
297         }
298         if (i < (globalInfo.number_entry - 1)) {
299             if (unzGoToNextFile(zipFile) != UNZ_OK) {
300                 return CloseZipFile(zipFile, false);
301             }
302         }
303     }
304     return CloseZipFile(zipFile, true);
305 }
306 
CloseZipFile(const unzFile zipFile,bool ret)307 bool CloseZipFile(const unzFile zipFile, bool ret)
308 {
309     unzClose(zipFile);
310     return ret;
311 }
312 
SortZipFile(ImageStructVec & imgVec)313 void SortZipFile(ImageStructVec& imgVec)
314 {
315     if (imgVec.size() == 0) {
316         return;
317     }
318 
319     sort(imgVec.begin(), imgVec.end(), [](std::shared_ptr<ImageStruct> image1,
320         std::shared_ptr<ImageStruct> image2)
321         -> bool {return image1->fileName < image2->fileName;});
322 }
323 
ReadImageFile(const unzFile zipFile,const std::string & fileName,ImageStructVec & imgVec,FrameRateConfig & frameConfig,unsigned long fileSize)324 bool ReadImageFile(const unzFile zipFile, const std::string& fileName, ImageStructVec& imgVec,
325     FrameRateConfig& frameConfig, unsigned long fileSize)
326 {
327     if (zipFile == nullptr) {
328         LOGE("ReadImageFile failed, zip is null");
329         return false;
330     }
331     int readLen = UNZ_OK;
332     int totalLen = 0;
333     int size = static_cast<int>(fileSize);
334     char readBuffer[READ_SIZE] = {0};
335     std::shared_ptr<ImageStruct> imageStruct = std::make_shared<ImageStruct>();
336     imageStruct->memPtr.SetBufferSize(fileSize);
337     do {
338         readLen = unzReadCurrentFile(zipFile, readBuffer, READ_SIZE);
339         if (readLen < 0) {
340             LOGE("unzReadCurrentFile length error");
341             return false;
342         }
343         if (imageStruct->memPtr.memBuffer == nullptr) {
344             LOGE("ReadImageFile memPtr is null");
345             return false;
346         }
347         if (memcpy_s(imageStruct->memPtr.memBuffer + totalLen, size - totalLen, \
348             readBuffer, readLen) == EOK) {
349             totalLen += readLen;
350         }
351     } while (readLen > 0);
352 
353     if (totalLen > 0) {
354         LOGD("fileName: %{public}s, fileSize: %{public}d, totalLen: %{public}d", fileName.c_str(), size, totalLen);
355         if (strstr(fileName.c_str(), BOOT_PIC_CONFIG_FILE.c_str()) != nullptr) {
356             ParseImageConfig(imageStruct->memPtr.memBuffer, totalLen, frameConfig);
357         } else {
358             CheckImageData(fileName, imageStruct, totalLen, imgVec);
359         }
360     }
361     return true;
362 }
363 
ParseImageConfig(const char * fileBuffer,int totalsize,FrameRateConfig & frameConfig)364 bool ParseImageConfig(const char* fileBuffer, int totalsize, FrameRateConfig& frameConfig)
365 {
366     std::string JParamsString;
367     JParamsString.assign(fileBuffer, totalsize);
368     cJSON* overallData = cJSON_Parse(JParamsString.c_str());
369     if (overallData == nullptr) {
370         LOGE("parse image config failed");
371         return false;
372     }
373     cJSON* frameRate = cJSON_GetObjectItem(overallData, "FrameRate");
374     if (frameRate != nullptr && cJSON_IsNumber(frameRate)) {
375         frameConfig.frameRate = frameRate->valueint;
376         LOGI("freq: %{public}d", frameConfig.frameRate);
377     }
378     cJSON_Delete(overallData);
379     return true;
380 }
381 
CheckImageData(const std::string & fileName,std::shared_ptr<ImageStruct> imageStruct,int32_t bufferLen,ImageStructVec & imgVec)382 bool CheckImageData(const std::string& fileName, std::shared_ptr<ImageStruct> imageStruct,
383     int32_t bufferLen, ImageStructVec& imgVec)
384 {
385     if (imageStruct->memPtr.memBuffer == nullptr) {
386         LOGE("json file buffer is null");
387         return false;
388     }
389     auto data = std::make_shared<Rosen::Drawing::Data>();
390     data->BuildFromMalloc(imageStruct->memPtr.memBuffer, bufferLen);
391     if (data->GetData() == nullptr) {
392         LOGE("data memory data is null. update data failed");
393         return false;
394     }
395     imageStruct->memPtr.setOwnerShip(data);
396     imageStruct->fileName = fileName;
397     imageStruct->imageData = std::make_shared<Rosen::Drawing::Image>();
398 #ifdef RS_ENABLE_GPU
399     imageStruct->imageData->MakeFromEncoded(data);
400 #endif
401     imgVec.push_back(imageStruct);
402     return true;
403 }
404 
405 /**
406  * Transate vp to pixel.
407  *
408  * @param sideLen The short side length of screen.
409  * @param vp vp value.
410  * @return Returns the font size.
411  */
TranslateVp2Pixel(const int32_t sideLen,const int32_t vp)412 int32_t TranslateVp2Pixel(const int32_t sideLen, const int32_t vp)
413 {
414     std::string deviceType = GetDeviceType();
415     float ratio = RATIO_PHONE;
416     if (DEVICE_TYPE_PHONE != deviceType && DEVICE_TYPE_WEARABLE != deviceType) {
417         ratio = RATIO_OTHER;
418     }
419     return TranslateVp2Pixel(sideLen, vp, ratio);
420 }
421 
422 /**
423 * Transate vp to pixel.
424 *
425 * @param sideLen The short side length of screen.
426 * @param vp vp value.
427 * @param ratio ratio value.
428 * @return Returns the font size.
429 */
TranslateVp2Pixel(const int32_t sideLen,const int32_t vp,const float ratio)430 int32_t TranslateVp2Pixel(const int32_t sideLen, const int32_t vp, const float ratio)
431 {
432     if (ratio == 0) {
433         LOGE("invalid ratio");
434         return 0;
435     }
436     return static_cast<int32_t>(std::ceil(sideLen * HALF / ratio) / HALF * vp);
437 }
438 
ReadFile(const std::string & filePath)439 std::string ReadFile(const std::string &filePath)
440 {
441     std::string content;
442     if (filePath.empty() || filePath.length() > PATH_MAX) {
443         LOGE("filepath check failed.");
444         return content;
445     }
446     char tmpPath[PATH_MAX] = {0};
447     if (realpath(filePath.c_str(), tmpPath) == nullptr) {
448         LOGE("filepath check failed! %{public}s %{public}d %{public}s", filePath.c_str(), errno, ::strerror(errno));
449         return content;
450     }
451     std::ifstream infile;
452     infile.open(tmpPath);
453     if (!infile.is_open()) {
454         LOGE("failed to open file");
455         return content;
456     }
457 
458     getline(infile, content);
459     infile.close();
460     return content;
461 }
462 
GetHingeStatus()463 std::string GetHingeStatus()
464 {
465     if (!IsFileExisted(HING_STATUS_INFO_PATH)) {
466         LOGE("failed not exist");
467         return "";
468     }
469 
470     return ReadFile(HING_STATUS_INFO_PATH);
471 }
472 
GetSystemCurrentTime()473 int64_t GetSystemCurrentTime()
474 {
475     auto currentTime = std::chrono::duration_cast<std::chrono::milliseconds>
476         (std::chrono::steady_clock::now().time_since_epoch()).count();
477     return currentTime;
478 }
479 
GetDeviceType()480 std::string GetDeviceType()
481 {
482     return system::GetParameter("const.product.devicetype", "phone");
483 }
484 } // namespace OHOS
485