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