1 /*
2 * Copyright (c) 2024 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 "hsp_packager.h"
17
18 #include <string>
19
20 #include "constants.h"
21 #include "json/json_utils.h"
22 #include "log.h"
23
24 namespace OHOS {
25 namespace AppPackingTool {
HspPackager(const std::map<std::string,std::string> & parameterMap,std::string & resultReceiver)26 HspPackager::HspPackager(const std::map<std::string, std::string> ¶meterMap, std::string &resultReceiver)
27 : Packager(parameterMap, resultReceiver)
28 {}
29
InitAllowedParam()30 int32_t HspPackager::InitAllowedParam()
31 {
32 return ERR_OK;
33 }
PreProcess()34 int32_t HspPackager::PreProcess()
35 {
36 if (!CheckForceFlag()) {
37 return ERR_INVALID_VALUE;
38 }
39
40 bool ret = IsVerifyValidInHspCommonMode() && IsVerifyValidInHspMode();
41 if (!ret) {
42 return ERR_INVALID_VALUE;
43 }
44 return ERR_OK;
45 }
Process()46 int32_t HspPackager::Process()
47 {
48 if (!CompressHsp()) {
49 std::string outPath;
50 if (parameterMap_.find(Constants::PARAM_OUT_PATH) != parameterMap_.end()) {
51 outPath = parameterMap_.at(Constants::PARAM_OUT_PATH);
52 }
53 if (fs::exists(outPath)) {
54 fs::remove_all(outPath);
55 }
56 LOGE("Hsp Process failed!");
57 return ERR_INVALID_VALUE;
58 }
59 return ERR_OK;
60 }
PostProcess()61 int32_t HspPackager::PostProcess()
62 {
63 if (generateBuildHash_) {
64 if (!CompressHsp()) {
65 std::string outPath;
66 if (parameterMap_.find(Constants::PARAM_OUT_PATH) != parameterMap_.end()) {
67 outPath = parameterMap_.at(Constants::PARAM_OUT_PATH);
68 }
69 if (fs::exists(outPath)) {
70 fs::remove_all(outPath);
71 }
72 LOGE("sencond CompressHsp failed!");
73 return ERR_INVALID_VALUE;
74 }
75 }
76 return ERR_OK;
77 }
78
IsVerifyValidInHspCommonMode()79 bool HspPackager::IsVerifyValidInHspCommonMode()
80 {
81 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(Constants::PARAM_JSON_PATH);
82 if (it == parameterMap_.end() || it->second.empty()) {
83 LOGE("HspPackager::isArgsValidInHspMode json-path is empty.");
84 return false;
85 }
86 jsonPath_ = it->second;
87 if (!IsPathValid(it->second, true, Constants::MODULE_JSON)) {
88 LOGE("HspPackager::isArgsValidInHspMode json-path must be module.json file.");
89 return false;
90 }
91 if (!Compatible(Constants::PARAM_JAR_PATH, formattedJarPathList_, Constants::JAR_SUFFIX) ||
92 !Compatible(Constants::PARAM_TXT_PATH, formattedTxtPathList_, Constants::TXT_SUFFIX)) {
93 return false;
94 }
95 if (!IsHspPathValid()) {
96 return false;
97 }
98 it = parameterMap_.find(Constants::PARAM_DIR_LIST);
99 if (it != parameterMap_.end() && !it->second.empty() &&
100 !SplitDirList(it->second, formatedDirList_)) {
101 LOGE("HspPackager::isArgsValidInHspMode --dir-list is invalid.");
102 return false;
103 }
104 it = parameterMap_.find(Constants::PARAM_PROFILE_PATH);
105 if (it != parameterMap_.end()) {
106 const std::string filePath = it->second;
107 if (!fs::is_regular_file(filePath) ||
108 fs::path(filePath).filename().string() != Constants::PROFILE_NAME) {
109 LOGE("HspPackager::isArgsValidInHspMode profile-path"
110 " must be CAPABILITY.profile file.");
111 return false;
112 }
113 }
114 it = parameterMap_.find(Constants::PARAM_PKG_CONTEXT_PATH);
115 if (it != parameterMap_.end() && !it ->second.empty()) {
116 const std::string filePath = it->second;
117 if (!fs::is_regular_file(filePath) ||
118 fs::path(filePath).filename().string() != Constants::PKG_CONTEXT_JSON) {
119 LOGE("HspPackager::isArgsValidInHspMode --pkg-context-path file"
120 " must be pkgContextInfo.json file.");
121 return false;
122 }
123 }
124 return true;
125 }
126
IsVerifyValidInHspMode()127 bool HspPackager::IsVerifyValidInHspMode()
128 {
129 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(Constants::PARAM_ETS_PATH);
130 if (it != parameterMap_.end()) {
131 const std::string filePath = it->second;
132 if (!filePath.empty() && !fs::exists(filePath)) {
133 LOGE("HspPackager::IsVerifyValidInHspMode --ets-path is invalid.");
134 return false;
135 }
136 }
137
138 std::string outPath = "";
139 std::string forceRewrite = "";
140 it = parameterMap_.find(Constants::PARAM_OUT_PATH);
141 if (it != parameterMap_.end()) {
142 outPath = it->second;
143 }
144
145 it = parameterMap_.find(Constants::PARAM_FORCE);
146 if (it != parameterMap_.end()) {
147 forceRewrite = it->second;
148 }
149
150 return IsOutPathValid(outPath, forceRewrite, Constants::HSP_SUFFIX);
151 }
152
Compatible(const std::string & paramPath,std::list<std::string> & fileList,const std::string & suffix)153 bool HspPackager::Compatible(const std::string ¶mPath, std::list<std::string> &fileList,
154 const std::string &suffix)
155 {
156 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(paramPath);
157 if (it != parameterMap_.end() && !it->second.empty() && !CompatibleProcess(it->second,
158 fileList, suffix)) {
159 LOGE("HspPackager::isArgsValidInHapMode %s is invalid.", paramPath.c_str());
160 return false;
161 }
162 return true;
163 }
164
IsHspPathValid()165 bool HspPackager::IsHspPathValid()
166 {
167 if (IsHspPathValid(Constants::PARAM_LIB_PATH)) {
168 LOGE("HspPackager::isArgsValidInHspMode lib-path is invalid.");
169 return false;
170 }
171 if (IsHspPathValid(Constants::PARAM_RES_PATH)) {
172 LOGE("HspPackager::isArgsValidInHspMode res-path is invalid.");
173 return false;
174 }
175 if (IsHspPathValid(Constants::PARAM_RESOURCES_PATH)) {
176 LOGE("HspPackager::isArgsValidInHspMode resources-path is invalid.");
177 return false;
178 }
179 if (IsHspPathValid(Constants::PARAM_ASSETS_PATH)) {
180 LOGE("HspPackager::isArgsValidInHspMode assets-path is invalid.");
181 return false;
182 }
183 if (IsHspPathValid(Constants::PARAM_AP_PATH)) {
184 LOGE("HspPackager::isArgsValidInHspMode ap-path is invalid.");
185 return false;
186 }
187 if (IsHspPathValid(Constants::PARAM_AN_PATH)) {
188 LOGE("HspPackager::isArgsValidInHspMode an-path is invalid.");
189 return false;
190 }
191 return true;
192 }
193
IsHspPathValid(const std::string & parameterMapKey)194 bool HspPackager::IsHspPathValid(const std::string ¶meterMapKey)
195 {
196 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(parameterMapKey);
197 if (it == parameterMap_.end()) {
198 return false;
199 }
200 const std::string path = it->second;
201 return (!path.empty() && !IsPathValid(path, false));
202 }
203
CompressHsp()204 bool HspPackager::CompressHsp()
205 {
206 if (!SetGenerateBuildHash(jsonPath_, generateBuildHash_, buildHashFinish_)) {
207 return false;
208 }
209 if (!moduleJson_.ParseFromFile(jsonPath_)) {
210 LOGE("ParseFromFile failed");
211 return false;
212 }
213 if (JsonUtils::IsModuleJson(jsonPath_)) {
214 if (!moduleJson_.CheckStageAsanTsanEnabledValid()) {
215 LOGE("CheckStageAsanTsanEnabledValid failed.");
216 return false;
217 }
218 if (!moduleJson_.CheckStageAtomicService()) {
219 LOGE("CheckStageAtomicService failed.");
220 return false;
221 }
222 if (!moduleJson_.CheckStageOverlayCfg()) {
223 LOGE("checkStageOverlayCfg failed.");
224 return false;
225 }
226 std::string moduleType;
227 if (!moduleJson_.GetStageModuleType(moduleType)) {
228 LOGW("GetStageModuleType failed.");
229 }
230 if (moduleType != Constants::TYPE_SHARED) {
231 LOGE("module type must be shared.");
232 return false;
233 }
234 }
235 if (!CompressHspMode(jsonPath_) || !BuildHash(buildHashFinish_, generateBuildHash_, parameterMap_, jsonPath_)) {
236 return false;
237 }
238 return true;
239 }
240
CompressHspMode(const std::string & jsonPath)241 bool HspPackager::CompressHspMode(const std::string &jsonPath)
242 {
243 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(Constants::PARAM_OUT_PATH);
244 std::string outPath;
245 if (it != parameterMap_.end()) {
246 outPath = it->second;
247 }
248 zipWrapper_.Open(outPath);
249 if (!zipWrapper_.IsOpen()) {
250 LOGE("HspPackager::Process: zipWrapper Open failed!");
251 return false;
252 }
253 std::string jsonString = moduleJson_.ToString();
254 if (!jsonString.empty()) {
255 std::string jsonType;
256 if (JsonUtils::IsModuleJson(jsonPath)) {
257 jsonType = Constants::MODULE_JSON;
258 if (!moduleJson_.GetStageModuleName(moduleName_) || moduleJson_.GetStageDeviceTypes(deviceTypes_)) {
259 LOGW("GetStageModuleName or GetStageDeviceTypes failed!");
260 }
261 } else {
262 jsonType = Constants::CONFIG_JSON;
263 if (!moduleJson_.GetFaModuleName(moduleName_) || moduleJson_.GetFaDeviceTypes(deviceTypes_)) {
264 LOGW("GetStageModuleName or GetStageDeviceTypes failed!");
265 }
266 }
267 if (zipWrapper_.WriteStringToZip(jsonString, jsonType) != ZipErrCode::ZIP_ERR_SUCCESS) {
268 LOGE("HspPackager::Process: zipWrapper WriteStringToZip failed!");
269 return false;
270 }
271 }
272
273 if (!AddCommonFileOrDirectoryToZip(Constants::PARAM_PROFILE_PATH, Constants::PROFILE_NAME)) {
274 return false;
275 }
276 it = parameterMap_.find(Constants::PARAM_INDEX_PATH);
277 if (it != parameterMap_.end() && !it->second.empty() && JsonUtils::IsModuleJson(jsonPath)) {
278 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, Constants::RESOURCES_INDEX) !=
279 ZipErrCode::ZIP_ERR_SUCCESS) {
280 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
281 return false;
282 }
283 }
284 return CompressHspModePartSecond(jsonPath);
285 }
286
CompressHspModePartSecond(const std::string & jsonPath)287 bool HspPackager::CompressHspModePartSecond(const std::string &jsonPath)
288 {
289 std::map<std::string, std::string> paramFileMap = {
290 {Constants::PARAM_LIB_PATH, Constants::LIB_PATH},
291 {Constants::PARAM_AN_PATH, Constants::AN_PATH},
292 {Constants::PARAM_AP_PATH, Constants::AP_PATH},
293 {Constants::PARAM_RPCID_PATH, Constants::RPCID_SC},
294 {Constants::PARAM_ASSETS_PATH, Constants::ASSETS_PATH}
295 };
296 for (auto& item : paramFileMap) {
297 if (!AddCommonFileOrDirectoryToZip(item.first, item.second)) {
298 return false;
299 }
300 }
301
302 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(Constants::PARAM_FILE_PATH);
303 if (it != parameterMap_.end() && !it->second.empty()) {
304 fs::path filePath = fs::path(it->second);
305 std::string zipPath = Constants::NULL_DIR_NAME;
306 if (!fs::is_directory(filePath)) {
307 zipPath = (filePath).filename().string();
308 }
309 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, zipPath) != ZipErrCode::ZIP_ERR_SUCCESS) {
310 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
311 return false;
312 }
313 }
314
315 it = parameterMap_.find(Constants::PARAM_RESOURCES_PATH);
316 if (it != parameterMap_.end() && !it->second.empty() && JsonUtils::IsModuleJson(jsonPath)) {
317 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, Constants::RESOURCES_PATH) != ZipErrCode::ZIP_ERR_SUCCESS) {
318 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
319 return false;
320 }
321 }
322 return CompressHspModePartThird(jsonPath);
323 }
324
CompressHspModePartThird(const std::string & jsonPath)325 bool HspPackager::CompressHspModePartThird(const std::string &jsonPath)
326 {
327 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(Constants::PARAM_RES_PATH);
328 if (it != parameterMap_.end() && !it->second.empty() && !moduleName_.empty()) {
329 std::string resPath = Constants::ASSETS_PATH + Constants::LINUX_FILE_SEPARATOR + moduleName_ +
330 Constants::LINUX_FILE_SEPARATOR + Constants::RESOURCES_PATH;
331 std::string deviceType;
332 if (!deviceTypes_.empty()) {
333 deviceType = deviceTypes_.front();
334 }
335 if (Constants::DEVICE_TYPE_FITNESSWATCH == deviceType ||
336 Constants::DEVICE_TYPE_FITNESSWATCH_NEW == deviceType) {
337 resPath = Constants::RES_PATH;
338 }
339 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, resPath) != ZipErrCode::ZIP_ERR_SUCCESS) {
340 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
341 return false;
342 }
343 }
344 it = parameterMap_.find(Constants::PARAM_JS_PATH);
345 if (it != parameterMap_.end() && !it->second.empty() && JsonUtils::IsModuleJson(jsonPath)) {
346 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, Constants::JS_PATH) != ZipErrCode::ZIP_ERR_SUCCESS) {
347 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
348 return false;
349 }
350 }
351 it = parameterMap_.find(Constants::PARAM_ETS_PATH);
352 if (it != parameterMap_.end() && !it->second.empty() && JsonUtils::IsModuleJson(jsonPath)) {
353 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, Constants::ETS_PATH) != ZipErrCode::ZIP_ERR_SUCCESS) {
354 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
355 return false;
356 }
357 }
358 return CompressHspModePartFourth();
359 }
360
CompressHspModePartFourth()361 bool HspPackager::CompressHspModePartFourth()
362 {
363 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(Constants::PARAM_BIN_PATH);
364 if (it != parameterMap_.end() && !it->second.empty()) {
365 fs::path filePath = fs::path(it->second);
366 std::string zipPath = Constants::NULL_DIR_NAME;
367 if (!fs::is_directory(filePath)) {
368 zipPath = (filePath).filename().string();
369 }
370 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, zipPath) != ZipErrCode::ZIP_ERR_SUCCESS) {
371 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
372 return false;
373 }
374 }
375 if (!AddCommonFileOrDirectoryToZip(Constants::PARAM_PACK_INFO_PATH, Constants::PACK_INFO)) {
376 return false;
377 }
378 if (!formatedDirList_.empty()) {
379 for (const auto& dirPath : formatedDirList_) {
380 std::string baseDir = fs::path(dirPath).filename().string();
381 if (zipWrapper_.AddFileOrDirectoryToZip(dirPath, baseDir) != ZipErrCode::ZIP_ERR_SUCCESS) {
382 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
383 return false;
384 }
385 }
386 }
387 it = parameterMap_.find(Constants::PARAM_PKG_CONTEXT_PATH);
388 if (it != parameterMap_.end() && !it->second.empty()) {
389 ModuleJson moduleJson;
390 if (!moduleJson.ParseFromFile(it->second)) {
391 LOGE("HspPackager::Process: moduleJson Read failed!");
392 return false;
393 }
394 std::string jsonString = moduleJson.ToString();
395 if (!jsonString.empty()) {
396 if (zipWrapper_.WriteStringToZip(jsonString, Constants::PKG_CONTEXT_JSON) != ZipErrCode::ZIP_ERR_SUCCESS) {
397 LOGE("HspPackager::Process: zipWrapper WriteStringToZip failed!");
398 return false;
399 }
400 } else {
401 LOGE("HspPackager::Process: jsonFile error!");
402 return false;
403 }
404 }
405 return CompressHspModeMultiple();
406 }
407
CompressHspModeMultiple()408 bool HspPackager::CompressHspModeMultiple()
409 {
410 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(Constants::PARAM_MAPLE_SO_DIR);
411 if (it != parameterMap_.end() && formattedSoPathList_.size() == 0 && !it->second.empty()) {
412 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, Constants::SO_DIR) != ZipErrCode::ZIP_ERR_SUCCESS) {
413 LOGE("HapPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
414 return false;
415 }
416 }
417
418 for (auto jarPathItem : formattedJarPathList_) {
419 std::string zipPath = fs::path(jarPathItem).filename().string();
420 if (zipWrapper_.AddFileOrDirectoryToZip(jarPathItem, zipPath) != ZipErrCode::ZIP_ERR_SUCCESS) {
421 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
422 return false;
423 }
424 }
425
426 for (auto txtPathItem : formattedTxtPathList_) {
427 std::string zipPath = fs::path(txtPathItem).filename().string();
428 if (zipWrapper_.AddFileOrDirectoryToZip(txtPathItem, zipPath) != ZipErrCode::ZIP_ERR_SUCCESS) {
429 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
430 return false;
431 }
432 }
433
434 it = parameterMap_.find(Constants::PARAM_SHAREDLIBS_PATH);
435 if (it != parameterMap_.end() && !it->second.empty()) {
436 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, Constants::SHARED_LIBS_DIR) !=
437 ZipErrCode::ZIP_ERR_SUCCESS) {
438 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
439 return false;
440 }
441 }
442 zipWrapper_.Close();
443 return true;
444 }
445
AddCommonFileOrDirectoryToZip(const std::string & paramPath,const std::string & targetPath)446 bool HspPackager::AddCommonFileOrDirectoryToZip(const std::string ¶mPath, const std::string &targetPath)
447 {
448 std::map<std::string, std::string>::const_iterator it = parameterMap_.find(paramPath);
449 if (it != parameterMap_.end() && !it->second.empty()) {
450 if (zipWrapper_.AddFileOrDirectoryToZip(it->second, targetPath) != ZipErrCode::ZIP_ERR_SUCCESS) {
451 LOGE("HspPackager::Process: zipWrapper AddFileOrDirectoryToZip failed!");
452 return false;
453 }
454 }
455 return true;
456 }
457 } // namespace AppPackingTool
458 } // namespace OHOS