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 "pack_info_utils.h"
17
18 #include <fstream>
19
20 #include "log.h"
21
22 namespace OHOS {
23 namespace AppPackingTool {
24 namespace {
25 const std::string DEFAULT_BUNDLE_TYPE = "APP";
26 const std::string MODULE = "module";
27 const std::string PACKAGES = "packages";
28 const char DOT = '.';
29 }
30
31 // java : mergeTwoPackInfo
MergeTwoPackInfos(const std::string& srcPackInfoJsonStr1, const std::string& srcPackInfoJsonStr2, std::string& dstPackInfoJsonStr)32 bool PackInfoUtils::MergeTwoPackInfos(const std::string& srcPackInfoJsonStr1, const std::string& srcPackInfoJsonStr2,
33 std::string& dstPackInfoJsonStr)
34 {
35 PackInfo srcPackInfo1;
36 PackInfo srcPackInfo2;
37 if (!srcPackInfo1.ParseFromString(srcPackInfoJsonStr1)) {
38 LOGE("Parse from string1 failed![%s]", srcPackInfoJsonStr1.c_str());
39 return false;
40 }
41 if (!srcPackInfo2.ParseFromString(srcPackInfoJsonStr2)) {
42 LOGE("Parse from string2 failed![%s]", srcPackInfoJsonStr2.c_str());
43 return false;
44 }
45 if (!VerifyPackInfos(srcPackInfo1, srcPackInfo2)) {
46 LOGE("VerifyPackInfos failed!");
47 return false;
48 }
49 if (!MergeTwoPackInfos(srcPackInfo1, srcPackInfo2)) {
50 LOGE("MergeTwoPackInfos failed!");
51 return false;
52 }
53 dstPackInfoJsonStr = srcPackInfo1.ToString();
54 return true;
55 }
56
57 // java : mergePackInfoObj
MergeTwoPackInfos(PackInfo& srcPackInfo1, PackInfo& srcPackInfo2)58 bool PackInfoUtils::MergeTwoPackInfos(PackInfo& srcPackInfo1, PackInfo& srcPackInfo2)
59 {
60 std::unique_ptr<PtJson> modulesObj1;
61 std::unique_ptr<PtJson> modulesObj2;
62 if (!srcPackInfo1.GetModulesObject(modulesObj1) || !srcPackInfo2.GetModulesObject(modulesObj2)) {
63 LOGE("Get module node from srcPackInfo1 or srcPackInfo2 failed!");
64 return false;
65 }
66 if (!modulesObj1->IsArray() || !modulesObj2->IsArray()) {
67 LOGE("Module node is not array!");
68 return false;
69 }
70 for (int32_t i = 0; i < modulesObj2->GetSize(); i++) {
71 if (!modulesObj1->Push(modulesObj2->Get(i))) {
72 LOGE("Push module node failed!");
73 return false;
74 }
75 }
76
77 std::unique_ptr<PtJson> packagesObj1;
78 std::unique_ptr<PtJson> packagesObj2;
79 if (!srcPackInfo1.GetPackagesObject(packagesObj1) || !srcPackInfo2.GetPackagesObject(packagesObj2)) {
80 LOGE("GetPackagesObject failed!");
81 return false;
82 }
83 if (!packagesObj1->IsArray() || !packagesObj2->IsArray()) {
84 LOGE("Package node is not array!");
85 return false;
86 }
87 for (int32_t i = 0; i < packagesObj2->GetSize(); i++) {
88 if (!packagesObj1->Push(packagesObj2->Get(i))) {
89 LOGE("Push package node failed!");
90 return false;
91 }
92 }
93 return true;
94 }
95
96 // java : mergeTwoPackInfoByPackagePair
MergeTwoPackInfosByPackagePair(const std::string& srcPackInfoJsonStr1, const std::string& srcPackInfoJsonStr2, const std::map<std::string, std::string>& packagesMap, std::string& dstPackInfoJsonStr)97 bool PackInfoUtils::MergeTwoPackInfosByPackagePair(const std::string& srcPackInfoJsonStr1,
98 const std::string& srcPackInfoJsonStr2, const std::map<std::string, std::string>& packagesMap,
99 std::string& dstPackInfoJsonStr)
100 {
101 PackInfo srcPackInfo1;
102 PackInfo srcPackInfo2;
103 if (!srcPackInfo1.ParseFromString(srcPackInfoJsonStr1)) {
104 LOGE("Parse from string1 failed![%s]", srcPackInfoJsonStr1.c_str());
105 return false;
106 }
107 if (!srcPackInfo2.ParseFromString(srcPackInfoJsonStr2)) {
108 LOGE("Parse from string2 failed![%s]", srcPackInfoJsonStr2.c_str());
109 return false;
110 }
111 if (!VerifyPackInfos(srcPackInfo1, srcPackInfo2)) {
112 LOGE("VerifyPackInfos failed!");
113 return false;
114 }
115 auto iter = packagesMap.begin();
116 while (iter != packagesMap.end()) {
117 std::string packageName = iter->first;
118 std::string moduleName = iter->second;
119 std::string tmpStr = packageName.substr(0, packageName.find_last_of(DOT));
120 if (!MergeTwoPackInfosByPackagePair(srcPackInfo1, srcPackInfo2, tmpStr, moduleName)) {
121 LOGE("MergeTwoPackInfosByPackagePair failed!");
122 return false;
123 }
124 ++iter;
125 }
126 dstPackInfoJsonStr = srcPackInfo1.ToString();
127 return true;
128 }
129
FindAndMergeModulesByPackagePair(PackInfo& srcPackInfo1, PackInfo& srcPackInfo2, const std::string& moduleName)130 bool PackInfoUtils::FindAndMergeModulesByPackagePair(PackInfo& srcPackInfo1, PackInfo& srcPackInfo2,
131 const std::string& moduleName)
132 {
133 std::unique_ptr<PtJson> modulesObj1;
134 std::unique_ptr<PtJson> modulesObj2;
135 if (!srcPackInfo1.GetModulesObject(modulesObj1) || !srcPackInfo2.GetModulesObject(modulesObj2)) {
136 LOGE("Get module node from srcPackInfo1 or srcPackInfo2 failed!");
137 return false;
138 }
139 if (!modulesObj1->IsArray() || !modulesObj2->IsArray()) {
140 LOGE("Module node is not array!");
141 return false;
142 }
143 bool isFind = false;
144 for (int32_t i = 0; i < modulesObj2->GetSize(); i++) {
145 std::unique_ptr<PtJson> distroObj;
146 if (!srcPackInfo2.GetDistroObject(i, distroObj)) {
147 LOGE("GetDistroObject failed!");
148 return false;
149 }
150 std::string moduleNameInDistroObj;
151 if (!srcPackInfo2.GetModuleNameByDistroObj(distroObj, moduleNameInDistroObj)) {
152 LOGE("GetModuleNameByDistroObj failed!");
153 return false;
154 }
155 if (moduleNameInDistroObj.compare(moduleName) == 0) {
156 if (!modulesObj1->Push(modulesObj2->Get(i))) {
157 LOGE("Push module node failed!");
158 return false;
159 }
160 isFind = true;
161 break;
162 }
163 }
164 if (!isFind) {
165 LOGE("Cannot find same moduleName in module node!");
166 return false;
167 }
168 return true;
169 }
170
FindAndMergePackagesByPackagePair(PackInfo& srcPackInfo1, PackInfo& srcPackInfo2, const std::string& packageName)171 bool PackInfoUtils::FindAndMergePackagesByPackagePair(PackInfo& srcPackInfo1, PackInfo& srcPackInfo2,
172 const std::string& packageName)
173 {
174 std::unique_ptr<PtJson> packagesObj1;
175 std::unique_ptr<PtJson> packagesObj2;
176 if (!srcPackInfo1.GetPackagesObject(packagesObj1) || !srcPackInfo2.GetPackagesObject(packagesObj2)) {
177 LOGE("Get package node from srcPackInfo1 or srcPackInfo2 failed!");
178 return false;
179 }
180 if (!packagesObj1->IsArray() || !packagesObj2->IsArray()) {
181 LOGE("Package node is not array!");
182 return false;
183 }
184 bool isFind = false;
185 for (int32_t i = 0; i < packagesObj2->GetSize(); i++) {
186 std::string packageNameInPackageObj;
187 if (!srcPackInfo2.GetNameByPackageObj(packagesObj2->Get(i), packageNameInPackageObj)) {
188 LOGE("GetNameByPackageObj failed!");
189 return false;
190 }
191 if (packageNameInPackageObj.compare(packageName) == 0) {
192 if (!packagesObj1->Push(packagesObj2->Get(i))) {
193 LOGE("Push Pacakge node failed!");
194 return false;
195 }
196 isFind = true;
197 break;
198 }
199 }
200 if (!isFind) {
201 LOGE("Cannot find same packageName in package node!");
202 return false;
203 }
204 return true;
205 }
206
207 // java : mergeTwoPackInfoObjByPackagePair
MergeTwoPackInfosByPackagePair(PackInfo& srcPackInfo1, PackInfo& srcPackInfo2, const std::string& packageName, const std::string& moduleName)208 bool PackInfoUtils::MergeTwoPackInfosByPackagePair(PackInfo& srcPackInfo1, PackInfo& srcPackInfo2,
209 const std::string& packageName, const std::string& moduleName)
210 {
211 if (!FindAndMergeModulesByPackagePair(srcPackInfo1, srcPackInfo2, moduleName)) {
212 LOGE("FindAndMergeModulesByPackagePair failed!");
213 return false;
214 }
215 if (!FindAndMergePackagesByPackagePair(srcPackInfo1, srcPackInfo2, packageName)) {
216 LOGE("FindAndMergePackagesByPackagePair failed!");
217 return false;
218 }
219 return true;
220 }
221
222 // java : verifyPackInfo
VerifyPackInfos(const PackInfo& packInfo1, const PackInfo& packInfo2)223 bool PackInfoUtils::VerifyPackInfos(const PackInfo& packInfo1, const PackInfo& packInfo2)
224 {
225 std::unique_ptr<PtJson> appObj1;
226 std::unique_ptr<PtJson> appObj2;
227 if (!const_cast<PackInfo&>(packInfo1).GetAppObject(appObj1) ||
228 !const_cast<PackInfo&>(packInfo2).GetAppObject(appObj2)) {
229 LOGE("GetAppObject failed!");
230 return false;
231 }
232 if (!CheckBundleNameInPackInfo(packInfo1, packInfo2)) {
233 LOGE("CheckBundleNameInPackInfo failed!");
234 return false;
235 }
236 if (!CheckBundleTypeInPackInfo(packInfo1, packInfo2)) {
237 LOGE("CheckBundleTypeInPackInfo failed!");
238 return false;
239 }
240 if (!CheckVersionCodeInPackInfo(packInfo1, packInfo2)) {
241 LOGE("CheckVersionCodeInPackInfo failed!");
242 return false;
243 }
244 return true;
245 }
246
CheckBundleNameInPackInfo(const PackInfo& packInfo1, const PackInfo& packInfo2)247 bool PackInfoUtils::CheckBundleNameInPackInfo(const PackInfo& packInfo1, const PackInfo& packInfo2)
248 {
249 std::string bundleName1;
250 std::string bundleName2;
251 if (!const_cast<PackInfo&>(packInfo1).GetBundleName(bundleName1)) {
252 LOGE("GetBundleName from packInfo1 failed!");
253 return false;
254 }
255 if (!const_cast<PackInfo&>(packInfo2).GetBundleName(bundleName2)) {
256 LOGE("GetBundleName from packInfo2 failed!");
257 return false;
258 }
259 if (bundleName1.compare(bundleName2) != 0) {
260 LOGE("bundleName is not same");
261 return false;
262 }
263 return true;
264 }
265
CheckBundleTypeInPackInfo(const PackInfo& packInfo1, const PackInfo& packInfo2)266 bool PackInfoUtils::CheckBundleTypeInPackInfo(const PackInfo& packInfo1, const PackInfo& packInfo2)
267 {
268 std::string bundleType1;
269 std::string bundleType2;
270 if (!const_cast<PackInfo&>(packInfo1).GetBundleType(bundleType1, DEFAULT_BUNDLE_TYPE)) {
271 LOGE("GetBundleType from packInfo1 failed!");
272 return false;
273 }
274 if (!const_cast<PackInfo&>(packInfo2).GetBundleType(bundleType2, DEFAULT_BUNDLE_TYPE)) {
275 LOGE("GetBundleType from packInfo2 failed!");
276 return false;
277 }
278 if (bundleType1.compare(bundleType2) != 0) {
279 LOGE("bundleType is not same");
280 return false;
281 }
282 return true;
283 }
284
CheckVersionCodeInPackInfo(const PackInfo& packInfo1, const PackInfo& packInfo2)285 bool PackInfoUtils::CheckVersionCodeInPackInfo(const PackInfo& packInfo1, const PackInfo& packInfo2)
286 {
287 PackInfoVersion version1;
288 PackInfoVersion version2;
289 if (!const_cast<PackInfo&>(packInfo1).GetVersion(version1)) {
290 LOGE("GetVersion from packInfo1 failed!");
291 return false;
292 }
293 if (!const_cast<PackInfo&>(packInfo2).GetVersion(version2)) {
294 LOGE("GetVersion from packInfo2 failed!");
295 return false;
296 }
297 if (version1.code != version2.code) {
298 LOGE("Version is not same");
299 return false;
300 }
301 return true;
302 }
303 } // namespace AppPackingTool
304 } // namespace OHOS
305