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 "cJSON.h"
17 #include "util.h"
18
19 #include <event_handler.h>
20 #include <fstream>
21 #include <sstream>
22 #include <securec.h>
23 #include <sys/time.h>
24 #include <include/codec/SkCodec.h>
25
26 namespace OHOS {
GetNowTime()27 int64_t GetNowTime()
28 {
29 struct timeval start = {};
30 gettimeofday(&start, nullptr);
31 constexpr uint32_t secToUsec = 1000 * 1000;
32 return static_cast<int64_t>(start.tv_sec) * secToUsec + start.tv_usec;
33 }
34
PostTask(std::function<void ()> func,uint32_t delayTime)35 void PostTask(std::function<void()> func, uint32_t delayTime)
36 {
37 auto handler = AppExecFwk::EventHandler::Current();
38 if (handler) {
39 handler->PostTask(func, delayTime);
40 }
41 }
42
ReadCustomBootConfig(const std::string & path,BootCustomConfig & aniconfig)43 bool ReadCustomBootConfig(const std::string& path, BootCustomConfig& aniconfig)
44 {
45 char newpath[PATH_MAX + 1] = { 0x00 };
46 if (strlen(path.c_str()) > PATH_MAX || realpath(path.c_str(), newpath) == nullptr) {
47 LOGE("check config path fail! %{public}s %{public}d %{public}s", path.c_str(), errno, ::strerror(errno));
48 return false;
49 }
50
51 std::ifstream configFile;
52 configFile.open(newpath);
53 std::stringstream JFilterParamsStream;
54 JFilterParamsStream << configFile.rdbuf();
55 configFile.close();
56 std::string JParamsString = JFilterParamsStream.str();
57
58 cJSON* overallData = cJSON_Parse(JParamsString.c_str());
59 if (overallData == nullptr) {
60 LOGE("The config json file fails to compile.");
61 return false;
62 }
63 cJSON* custPicPath = cJSON_GetObjectItem(overallData, "cust.bootanimation.pics");
64 if (custPicPath != nullptr && custPicPath->valuestring != nullptr) {
65 aniconfig.custPicZipPath = custPicPath->valuestring;
66 LOGI("cust piczip path: %{public}s", aniconfig.custPicZipPath.c_str());
67 }
68 cJSON* custSoundPath = cJSON_GetObjectItem(overallData, "cust.bootanimation.sounds");
69 if (custSoundPath != nullptr && custSoundPath->valuestring != nullptr) {
70 aniconfig.custSoundsPath = custSoundPath->valuestring;
71 LOGI("cust sound path: %{public}s", aniconfig.custSoundsPath.c_str());
72 }
73 cJSON* custVideoPath = cJSON_GetObjectItem(overallData, "cust.bootanimation.video");
74 if (custVideoPath != nullptr && custVideoPath->valuestring != nullptr) {
75 aniconfig.custVideoPath = custVideoPath->valuestring;
76 LOGI("cust video path: %{public}s", aniconfig.custVideoPath.c_str());
77 }
78 cJSON_Delete(overallData);
79 return true;
80 }
81
ReadJsonConfig(const char * filebuffer,int totalsize,BootAniConfig & aniconfig)82 bool ReadJsonConfig(const char* filebuffer, int totalsize, BootAniConfig& aniconfig)
83 {
84 std::string JParamsString;
85 JParamsString.assign(filebuffer, totalsize);
86 cJSON* overallData = cJSON_Parse(JParamsString.c_str());
87 if (overallData == nullptr) {
88 LOGE("The config json file fails to compile.");
89 return false;
90 }
91 cJSON* frameRate = cJSON_GetObjectItem(overallData, "FrameRate");
92 if (frameRate != nullptr) {
93 aniconfig.frameRate = frameRate->valueint;
94 LOGI("freq: %{public}d", aniconfig.frameRate);
95 }
96 cJSON_Delete(overallData);
97 return true;
98 }
99
GenImageData(const std::string & filename,std::shared_ptr<ImageStruct> imagetruct,int32_t bufferlen,ImageStructVec & outBgImgVec)100 bool GenImageData(const std::string& filename, std::shared_ptr<ImageStruct> imagetruct, int32_t bufferlen,
101 ImageStructVec& outBgImgVec)
102 {
103 if (imagetruct->memPtr.memBuffer == nullptr) {
104 LOGE("Json File buffer is null.");
105 return false;
106 }
107 auto skData = SkData::MakeFromMalloc(imagetruct->memPtr.memBuffer, bufferlen);
108 if (skData == nullptr) {
109 LOGE("skdata memory data is null. update data failed");
110 return false;
111 }
112 imagetruct->memPtr.setOwnerShip(skData);
113 auto codec = SkCodec::MakeFromData(skData);
114 imagetruct->fileName = filename;
115 imagetruct->imageData = SkImage::MakeFromEncoded(skData);
116 outBgImgVec.push_back(imagetruct);
117 return true;
118 }
119
ReadCurrentFile(const unzFile zipfile,const std::string & filename,ImageStructVec & outBgImgVec,BootAniConfig & aniconfig,unsigned long fileSize)120 bool ReadCurrentFile(const unzFile zipfile, const std::string& filename, ImageStructVec& outBgImgVec,
121 BootAniConfig& aniconfig, unsigned long fileSize)
122 {
123 if (zipfile == nullptr) {
124 LOGE("Readzip Json zipfile is null.");
125 return false;
126 }
127 int readlen = UNZ_OK;
128 int totalLen = 0;
129 int ifileSize = static_cast<int>(fileSize);
130 char readBuffer[READ_SIZE] = {0};
131 std::shared_ptr<ImageStruct> imagestrct = std::make_shared<ImageStruct>();
132 imagestrct->memPtr.SetBufferSize(fileSize);
133 do {
134 readlen = unzReadCurrentFile(zipfile, readBuffer, READ_SIZE);
135 if (readlen < 0) {
136 LOGE("Readzip readCurrFile failed");
137 return false;
138 }
139 if (imagestrct->memPtr.memBuffer == nullptr) {
140 LOGE("Readzip memPtr is null.");
141 return false;
142 }
143 if (memcpy_s(imagestrct->memPtr.memBuffer + totalLen, ifileSize - totalLen, \
144 readBuffer, readlen) == EOK) {
145 totalLen += readlen;
146 }
147 } while (readlen > 0);
148
149 if (totalLen > 0) {
150 LOGD("filename:%{public}s fileSize:%{public}d totalLen:%{public}d", filename.c_str(), ifileSize, totalLen);
151 if (strstr(filename.c_str(), BOOT_PIC_CONFIGFILE.c_str()) != nullptr) {
152 ReadJsonConfig(imagestrct->memPtr.memBuffer, totalLen, aniconfig);
153 } else {
154 GenImageData(filename, imagestrct, totalLen, outBgImgVec);
155 }
156 }
157 return true;
158 }
159
SortZipFile(ImageStructVec & outBgImgVec)160 void SortZipFile(ImageStructVec& outBgImgVec)
161 {
162 if (outBgImgVec.size() == 0) {
163 return;
164 }
165
166 sort(outBgImgVec.begin(), outBgImgVec.end(), [](std::shared_ptr<ImageStruct> image1,
167 std::shared_ptr<ImageStruct> image2)
168 -> bool {return image1->fileName < image2->fileName;});
169 }
170
ReadZipFile(const std::string & srcFilePath,ImageStructVec & outBgImgVec,BootAniConfig & aniconfig)171 bool ReadZipFile(const std::string& srcFilePath, ImageStructVec& outBgImgVec, BootAniConfig& aniconfig)
172 {
173 unzFile zipfile = unzOpen2(srcFilePath.c_str(), nullptr);
174 if (zipfile == nullptr) {
175 LOGE("Open Zipfile fail: %{public}s", srcFilePath.c_str());
176 return false;
177 }
178 unz_global_info globalInfo;
179 if (unzGetGlobalInfo(zipfile, &globalInfo) != UNZ_OK) {
180 unzClose(zipfile);
181 LOGE("Get ZipGlobalInfo fail");
182 return false;
183 }
184 LOGD("Readzip zip file num: %{public}ld", globalInfo.number_entry);
185 for (unsigned long i = 0; i < globalInfo.number_entry; ++i) {
186 unz_file_info fileInfo;
187 char filename[MAX_FILE_NAME] = {0};
188 if (unzGetCurrentFileInfo(zipfile, &fileInfo, filename, MAX_FILE_NAME, nullptr, 0, nullptr, 0) != UNZ_OK) {
189 unzClose(zipfile);
190 return false;
191 }
192 if (filename[strlen(filename) - 1] != '/') {
193 if (unzOpenCurrentFile(zipfile) != UNZ_OK) {
194 unzClose(zipfile);
195 return false;
196 }
197 std::string strfilename = std::string(filename);
198 size_t npos = strfilename.find_last_of("//");
199 if (npos != std::string::npos) {
200 strfilename = strfilename.substr(npos + 1, strfilename.length());
201 }
202 if (!ReadCurrentFile(zipfile, strfilename, outBgImgVec, aniconfig, fileInfo.uncompressed_size)) {
203 LOGE("Readzip deal single file failed");
204 unzCloseCurrentFile(zipfile);
205 unzClose(zipfile);
206 return false;
207 }
208 unzCloseCurrentFile(zipfile);
209 }
210 if (i < (globalInfo.number_entry - 1)) {
211 if (unzGoToNextFile(zipfile) != UNZ_OK) {
212 unzClose(zipfile);
213 return false;
214 }
215 }
216 }
217 return true;
218 }
219
WaitRenderServiceInit()220 void WaitRenderServiceInit()
221 {
222 while (true) {
223 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
224 if (samgr == nullptr) {
225 LOGI("samgr is null");
226 usleep(SLEEP_TIME_US);
227 continue;
228 }
229 sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(RENDER_SERVICE);
230 if (remoteObject != nullptr) {
231 LOGI("renderService is inited");
232 break;
233 } else {
234 LOGI("renderService is not inited, wait");
235 usleep(SLEEP_TIME_US);
236 }
237 }
238 }
239
IsFileExisted(const std::string & filePath)240 bool IsFileExisted(const std::string& filePath)
241 {
242 if (filePath.empty()) {
243 LOGE("check filepath is empty");
244 return false;
245 }
246 char newpath[PATH_MAX + 1] = { 0x00 };
247 if (strlen(filePath.c_str()) > PATH_MAX || realpath(filePath.c_str(), newpath) == nullptr) {
248 LOGE("check filepath fail! %{public}s %{public}d %{public}s", filePath.c_str(), errno, ::strerror(errno));
249 return false;
250 }
251 struct stat info = {0};
252 if (stat(newpath, &info) != 0) {
253 LOGE("stat filepath fail! %{public}s %{public}d %{public}s", filePath.c_str(), errno, ::strerror(errno));
254 return false;
255 }
256 return true;
257 }
258 } // namespace OHOS
259