1 /*
2 * Copyright (c) 2025 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 "plugin_bundle_info.h"
17
18 #include "app_log_wrapper.h"
19 #include "json_util.h"
20 #include "nlohmann/json.hpp"
21 #include "parcel_macro.h"
22 #include "string_ex.h"
23
24 namespace OHOS {
25 namespace AppExecFwk {
26 namespace {
27 const char* PLUGIN_BUNDLE_INFO_PLUGIN_BUNDLE_NAME = "pluginBundleName";
28 const char* PLUGIN_BUNDLE_INFO_LABEL = "label";
29 const char* PLUGIN_BUNDLE_INFO_ICON = "icon";
30 const char* PLUGIN_BUNDLE_INFO_VERSION_NAME = "versionName";
31 const char* PLUGIN_BUNDLE_INFO_ICON_ID = "iconId";
32 const char* PLUGIN_BUNDLE_INFO_LABEL_ID = "labelId";
33 const char* PLUGIN_BUNDLE_INFO_VERSION_CODE = "versionCode";
34 const char* PLUGIN_BUNDLE_INFO_APP_IDENTIFIER = "appIdentifier";
35 const char* PLUGIN_BUNDLE_INFO_APP_ID = "appId";
36 const char* PLUGIN_BUNDLE_INFO_CODE_PATH = "codePath";
37 const char* PLUGIN_BUNDLE_INFO_MODULE_INFOS = "pluginModuleInfos";
38 const char* PLUGIN_BUNDLE_INFO_ABILITY_INFOS = "abilityInfos";
39 const char* PLUGIN_BUNDLE_INFO_APPLICATION_INFO = "appInfo";
40 const char* PLUGIN_BUNDLE_INFO_NATIVE_LIB_PATH = "nativeLibraryPath";
41 const char* COMPILE_MODE_ES_MODULE = "esmodule";
42 }
43
ReadFromParcel(Parcel & parcel)44 bool PluginBundleInfo::ReadFromParcel(Parcel &parcel)
45 {
46 iconId = parcel.ReadUint32();
47 labelId = parcel.ReadUint32();
48 versionCode = parcel.ReadUint32();
49
50 pluginBundleName = parcel.ReadString();
51 label = parcel.ReadString();
52 icon = parcel.ReadString();
53 versionName = parcel.ReadString();
54 appIdentifier = parcel.ReadString();
55 appId = parcel.ReadString();
56 codePath = parcel.ReadString();
57 nativeLibraryPath = parcel.ReadString();
58
59 int32_t size;
60 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, size);
61 CONTAINER_SECURITY_VERIFY(parcel, size, &pluginModuleInfos);
62 for (auto i = 0; i < size; i++) {
63 std::unique_ptr<PluginModuleInfo> info(parcel.ReadParcelable<PluginModuleInfo>());
64 if (!info) {
65 APP_LOGE("ReadParcelable<PluginModuleInfo> failed");
66 return false;
67 }
68 pluginModuleInfos.emplace_back(*info);
69 }
70
71 int32_t abilityInfoSize;
72 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, abilityInfoSize);
73 CONTAINER_SECURITY_VERIFY(parcel, abilityInfoSize, &abilityInfos);
74 for (auto i = 0; i < abilityInfoSize; i++) {
75 std::string name = parcel.ReadString();
76 std::unique_ptr<AbilityInfo> info(parcel.ReadParcelable<AbilityInfo>());
77 if (!info) {
78 APP_LOGE("ReadParcelable<AbilityInfo> failed");
79 return false;
80 }
81 abilityInfos.emplace(name, *info);
82 }
83 std::unique_ptr<ApplicationInfo> applicationInfo(parcel.ReadParcelable<ApplicationInfo>());
84 if (!applicationInfo) {
85 APP_LOGE("ReadParcelable<ApplicationInfo> failed");
86 return false;
87 }
88 appInfo = *applicationInfo;
89
90 return true;
91 }
92
Marshalling(Parcel & parcel) const93 bool PluginBundleInfo::Marshalling(Parcel &parcel) const
94 {
95 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, iconId);
96 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, labelId);
97 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, versionCode);
98
99 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, pluginBundleName);
100 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, label);
101 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, icon);
102 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, versionName);
103 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, appIdentifier);
104 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, appId);
105 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, codePath);
106 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, nativeLibraryPath);
107
108 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, pluginModuleInfos.size());
109 for (auto &info : pluginModuleInfos) {
110 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &info);
111 }
112 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, abilityInfos.size());
113 for (const auto &abilityInfo : abilityInfos) {
114 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, abilityInfo.first);
115 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &abilityInfo.second);
116 }
117 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &appInfo);
118 return true;
119 }
120
Unmarshalling(Parcel & parcel)121 PluginBundleInfo *PluginBundleInfo::Unmarshalling(Parcel &parcel)
122 {
123 PluginBundleInfo *info = new (std::nothrow) PluginBundleInfo();
124 if (info && !info->ReadFromParcel(parcel)) {
125 APP_LOGW("read from parcel failed");
126 delete info;
127 info = nullptr;
128 }
129 return info;
130 }
131
to_json(nlohmann::json & jsonObject,const PluginBundleInfo & pluginBundleInfo)132 void to_json(nlohmann::json &jsonObject, const PluginBundleInfo &pluginBundleInfo)
133 {
134 jsonObject = nlohmann::json {
135 {PLUGIN_BUNDLE_INFO_PLUGIN_BUNDLE_NAME, pluginBundleInfo.pluginBundleName},
136 {PLUGIN_BUNDLE_INFO_LABEL, pluginBundleInfo.label},
137 {PLUGIN_BUNDLE_INFO_ICON, pluginBundleInfo.icon},
138 {PLUGIN_BUNDLE_INFO_VERSION_NAME, pluginBundleInfo.versionName},
139 {PLUGIN_BUNDLE_INFO_APP_IDENTIFIER, pluginBundleInfo.appIdentifier},
140 {PLUGIN_BUNDLE_INFO_APP_ID, pluginBundleInfo.appId},
141 {PLUGIN_BUNDLE_INFO_ICON_ID, pluginBundleInfo.iconId},
142 {PLUGIN_BUNDLE_INFO_LABEL_ID, pluginBundleInfo.labelId},
143 {PLUGIN_BUNDLE_INFO_VERSION_CODE, pluginBundleInfo.versionCode},
144 {PLUGIN_BUNDLE_INFO_MODULE_INFOS, pluginBundleInfo.pluginModuleInfos},
145 {PLUGIN_BUNDLE_INFO_CODE_PATH, pluginBundleInfo.codePath},
146 {PLUGIN_BUNDLE_INFO_NATIVE_LIB_PATH, pluginBundleInfo.nativeLibraryPath},
147 {PLUGIN_BUNDLE_INFO_ABILITY_INFOS, pluginBundleInfo.abilityInfos},
148 {PLUGIN_BUNDLE_INFO_APPLICATION_INFO, pluginBundleInfo.appInfo}
149 };
150 }
151
from_json(const nlohmann::json & jsonObject,PluginBundleInfo & pluginBundleInfo)152 void from_json(const nlohmann::json &jsonObject, PluginBundleInfo &pluginBundleInfo)
153 {
154 const auto &jsonObjectEnd = jsonObject.end();
155 int32_t parseResult = ERR_OK;
156 BMSJsonUtil::GetStrValueIfFindKey(jsonObject,
157 jsonObjectEnd,
158 PLUGIN_BUNDLE_INFO_PLUGIN_BUNDLE_NAME,
159 pluginBundleInfo.pluginBundleName,
160 false,
161 parseResult);
162 BMSJsonUtil::GetStrValueIfFindKey(jsonObject,
163 jsonObjectEnd,
164 PLUGIN_BUNDLE_INFO_LABEL,
165 pluginBundleInfo.label,
166 false,
167 parseResult);
168 BMSJsonUtil::GetStrValueIfFindKey(jsonObject,
169 jsonObjectEnd,
170 PLUGIN_BUNDLE_INFO_ICON,
171 pluginBundleInfo.icon,
172 false,
173 parseResult);
174 BMSJsonUtil::GetStrValueIfFindKey(jsonObject,
175 jsonObjectEnd,
176 PLUGIN_BUNDLE_INFO_VERSION_NAME,
177 pluginBundleInfo.versionName,
178 false,
179 parseResult);
180 BMSJsonUtil::GetStrValueIfFindKey(jsonObject,
181 jsonObjectEnd,
182 PLUGIN_BUNDLE_INFO_APP_IDENTIFIER,
183 pluginBundleInfo.appIdentifier,
184 false,
185 parseResult);
186 BMSJsonUtil::GetStrValueIfFindKey(jsonObject,
187 jsonObjectEnd,
188 PLUGIN_BUNDLE_INFO_APP_ID,
189 pluginBundleInfo.appId,
190 false,
191 parseResult);
192 GetValueIfFindKey<uint32_t>(jsonObject,
193 jsonObjectEnd,
194 PLUGIN_BUNDLE_INFO_ICON_ID,
195 pluginBundleInfo.iconId,
196 JsonType::NUMBER,
197 false,
198 parseResult,
199 ArrayType::NOT_ARRAY);
200 GetValueIfFindKey<uint32_t>(jsonObject,
201 jsonObjectEnd,
202 PLUGIN_BUNDLE_INFO_LABEL_ID,
203 pluginBundleInfo.labelId,
204 JsonType::NUMBER,
205 false,
206 parseResult,
207 ArrayType::NOT_ARRAY);
208 GetValueIfFindKey<uint32_t>(jsonObject,
209 jsonObjectEnd,
210 PLUGIN_BUNDLE_INFO_VERSION_CODE,
211 pluginBundleInfo.versionCode,
212 JsonType::NUMBER,
213 false,
214 parseResult,
215 ArrayType::NOT_ARRAY);
216 GetValueIfFindKey<std::vector<PluginModuleInfo>>(jsonObject,
217 jsonObjectEnd,
218 PLUGIN_BUNDLE_INFO_MODULE_INFOS,
219 pluginBundleInfo.pluginModuleInfos,
220 JsonType::ARRAY,
221 false,
222 parseResult,
223 ArrayType::OBJECT);
224 BMSJsonUtil::GetStrValueIfFindKey(jsonObject,
225 jsonObjectEnd,
226 PLUGIN_BUNDLE_INFO_CODE_PATH,
227 pluginBundleInfo.codePath,
228 false,
229 parseResult);
230 BMSJsonUtil::GetStrValueIfFindKey(jsonObject,
231 jsonObjectEnd,
232 PLUGIN_BUNDLE_INFO_NATIVE_LIB_PATH,
233 pluginBundleInfo.nativeLibraryPath,
234 false,
235 parseResult);
236 GetValueIfFindKey<std::unordered_map<std::string, AbilityInfo>>(jsonObject,
237 jsonObjectEnd,
238 PLUGIN_BUNDLE_INFO_ABILITY_INFOS,
239 pluginBundleInfo.abilityInfos,
240 JsonType::OBJECT,
241 false,
242 parseResult,
243 ArrayType::NOT_ARRAY);
244 GetValueIfFindKey<ApplicationInfo>(jsonObject,
245 jsonObjectEnd,
246 PLUGIN_BUNDLE_INFO_APPLICATION_INFO,
247 pluginBundleInfo.appInfo,
248 JsonType::OBJECT,
249 false,
250 parseResult,
251 ArrayType::NOT_ARRAY);
252 if (parseResult != ERR_OK) {
253 APP_LOGE("read pluginBundleInfo error : %{public}d", parseResult);
254 }
255 }
256
GetAbilityInfoByName(const std::string & abilityName,const std::string & moduleName,AbilityInfo & info)257 bool PluginBundleInfo::GetAbilityInfoByName(const std::string &abilityName,
258 const std::string &moduleName,
259 AbilityInfo &info)
260 {
261 for (const auto &ability : abilityInfos) {
262 auto &abilityInfo = ability.second;
263 if ((abilityInfo.name == abilityName) &&
264 (moduleName.empty() || (abilityInfo.moduleName == moduleName))) {
265 info = abilityInfo;
266 info.applicationInfo = appInfo;
267 return true;
268 }
269 }
270 return false;
271 }
272
GetHapModuleInfo(const std::string & moduleName,HapModuleInfo & hapInfo)273 bool PluginBundleInfo::GetHapModuleInfo(const std::string &moduleName,
274 HapModuleInfo &hapInfo)
275 {
276 for (const auto &moduleInfo : pluginModuleInfos) {
277 if (moduleInfo.moduleName == moduleName) {
278 hapInfo.moduleName = moduleInfo.moduleName;
279 hapInfo.hapPath = moduleInfo.hapPath;
280 hapInfo.nativeLibraryPath = moduleInfo.nativeLibraryPath;
281 hapInfo.cpuAbi = moduleInfo.cpuAbi;
282 hapInfo.isLibIsolated = moduleInfo.isLibIsolated;
283 hapInfo.compressNativeLibs = moduleInfo.compressNativeLibs;
284 hapInfo.descriptionId = moduleInfo.descriptionId;
285 hapInfo.description = moduleInfo.description;
286 hapInfo.nativeLibraryFileNames = moduleInfo.nativeLibraryFileNames;
287 hapInfo.bundleName = pluginBundleName;
288 hapInfo.packageName = moduleInfo.packageName;
289 hapInfo.name = moduleInfo.moduleName;
290 hapInfo.package = moduleInfo.moduleName;
291 hapInfo.isModuleJson = true;
292 hapInfo.compileMode = (moduleInfo.compileMode == COMPILE_MODE_ES_MODULE) ?
293 CompileMode::ES_MODULE : CompileMode::JS_BUNDLE;
294 std::string key;
295 key.append(".").append(moduleName).append(".");
296 for (const auto &ability : abilityInfos) {
297 if ((ability.first.find(key) != std::string::npos) &&
298 (ability.second.moduleName == hapInfo.moduleName)) {
299 auto &abilityInfo = hapInfo.abilityInfos.emplace_back(ability.second);
300 abilityInfo.applicationInfo = appInfo;
301 }
302 }
303 return true;
304 }
305 }
306 return false;
307 }
308 } // AppExecFwk
309 } // OHOS
310