1 /*
2 * Copyright (c) 2024-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 "js_runtime_lite.h"
17
18 #include <regex>
19
20 #include "bundle_mgr_interface.h"
21 #include "hilog_tag_wrapper.h"
22 #include "iservice_registry.h"
23 #include "js_environment.h"
24 #include "js_module_reader.h"
25 #include "js_runtime_common.h"
26 #include "js_worker.h"
27 #include "ohos_js_env_logger.h"
28 #include "ohos_js_environment_impl.h"
29 #include "parameters.h"
30 #include "system_ability_definition.h"
31 #include "native_engine/native_create_env.h"
32 #include "worker_info.h"
33
34 using Extractor = OHOS::AbilityBase::Extractor;
35 using ExtractorUtil = OHOS::AbilityBase::ExtractorUtil;
36
37 namespace OHOS {
38 namespace AbilityRuntime {
39 namespace {
40 constexpr int64_t DEFAULT_GC_POOL_SIZE = 0x10000000; // 256MB
41 const std::string SANDBOX_ARK_PROIFILE_PATH = "/data/storage/ark-profile";
42 const std::string PACKAGE_NAME = "packageName";
43 const std::string BUNDLE_NAME = "bundleName";
44 const std::string MODULE_NAME = "moduleName";
45 const std::string VERSION = "version";
46 const std::string ENTRY_PATH = "entryPath";
47 const std::string IS_SO = "isSO";
48 const std::string DEPENDENCY_ALIAS = "dependencyAlias";
PrintVmLog(int32_t,int32_t,const char *,const char *,const char * message)49 int32_t PrintVmLog(int32_t, int32_t, const char*, const char*, const char* message)
50 {
51 TAG_LOGI(AAFwkTag::JSRUNTIME, "ArkLog: %{public}s", message);
52 return 0;
53 }
54 }
JsRuntimeLite()55 JsRuntimeLite::JsRuntimeLite()
56 {}
57
~JsRuntimeLite()58 JsRuntimeLite::~JsRuntimeLite()
59 {
60 std::lock_guard<std::mutex> lock(envMutex_);
61 for (auto it : envMap_) {
62 it.second.reset();
63 it.second = nullptr;
64 }
65 envMap_.clear();
66 threadIds_.clear();
67 }
68
GetInstance()69 JsRuntimeLite& JsRuntimeLite::GetInstance()
70 {
71 static JsRuntimeLite jsRuntimeLite;
72 return jsRuntimeLite;
73 }
74
CreateNapiEnv(napi_env * env)75 napi_status CreateNapiEnv(napi_env *env)
76 {
77 TAG_LOGD(AAFwkTag::JSRUNTIME, "Called");
78 if (env == nullptr) {
79 TAG_LOGE(AAFwkTag::JSRUNTIME, "null env");
80 return napi_status::napi_invalid_arg;
81 }
82 auto options = JsRuntimeLite::GetInstance().GetChildOptions();
83 if (options == nullptr) {
84 TAG_LOGE(AAFwkTag::JSRUNTIME, "null options");
85 return napi_status::napi_generic_failure;
86 }
87 std::shared_ptr<OHOS::JsEnv::JsEnvironment> jsEnv = nullptr;
88 auto errCode = JsRuntimeLite::GetInstance().CreateJsEnv(*options, jsEnv);
89 if (errCode != napi_status::napi_ok) {
90 TAG_LOGE(AAFwkTag::JSRUNTIME, "CreateJsEnv failed");
91 return errCode;
92 }
93 *env = reinterpret_cast<napi_env>(jsEnv->GetNativeEngine());
94 if (env == nullptr) {
95 TAG_LOGE(AAFwkTag::JSRUNTIME, "null env");
96 return napi_status::napi_generic_failure;
97 }
98 if (JsRuntimeCommon::GetInstance().IsDebugMode()) {
99 auto nativeEngine = jsEnv->GetNativeEngine();
100 const std::string threadName = "childThread";
101 napi_status errCode = JsRuntimeCommon::GetInstance().StartDebugMode(nativeEngine, threadName);
102 if (errCode != napi_status::napi_ok) {
103 TAG_LOGE(AAFwkTag::JSRUNTIME, "start debug mode failed");
104 }
105 }
106 return JsRuntimeLite::GetInstance().Init(*options, *env);
107 }
108
DestroyNapiEnv(napi_env * env)109 napi_status DestroyNapiEnv(napi_env *env)
110 {
111 TAG_LOGD(AAFwkTag::JSRUNTIME, "Called");
112 if (env == nullptr) {
113 TAG_LOGE(AAFwkTag::JSRUNTIME, "null env");
114 return napi_status::napi_invalid_arg;
115 }
116 if (JsRuntimeCommon::GetInstance().IsDebugMode()) {
117 auto jsEnv = JsRuntimeLite::GetInstance().GetJsEnv(*env);
118 if (jsEnv == nullptr) {
119 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv");
120 return napi_status::napi_generic_failure;
121 }
122 auto nativeEngine = jsEnv->GetNativeEngine();
123 if (nativeEngine == nullptr) {
124 TAG_LOGE(AAFwkTag::JSRUNTIME, "null nativeEngine");
125 return napi_status::napi_generic_failure;
126 }
127 napi_status errCode = JsRuntimeCommon::GetInstance().StopDebugMode(nativeEngine);
128 if (errCode != napi_status::napi_ok) {
129 TAG_LOGE(AAFwkTag::JSRUNTIME, "stop debug mode failed");
130 }
131 }
132 auto errCode = JsRuntimeLite::GetInstance().RemoveJsEnv(*env);
133 if (errCode == napi_status::napi_ok) {
134 *env = nullptr;
135 }
136 return errCode;
137 }
138
InitJsRuntimeLite(const Options & options)139 void JsRuntimeLite::InitJsRuntimeLite(const Options& options)
140 {
141 if (options.isUnique) {
142 return;
143 }
144 GetInstance().SetChildOptions(options);
145 NativeCreateEnv::RegCreateNapiEnvCallback(CreateNapiEnv);
146 NativeCreateEnv::RegDestroyNapiEnvCallback(DestroyNapiEnv);
147 }
148
CreateJsEnv(const Options & options,std::shared_ptr<JsEnv::JsEnvironment> & jsEnv)149 napi_status JsRuntimeLite::CreateJsEnv(const Options& options, std::shared_ptr<JsEnv::JsEnvironment>& jsEnv)
150 {
151 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
152 panda::RuntimeOption pandaOption;
153 int arkProperties = OHOS::system::GetIntParameter<int>("persist.ark.properties", -1);
154 std::string bundleName = OHOS::system::GetParameter("persist.ark.arkbundlename", "");
155 std::string memConfigProperty = OHOS::system::GetParameter("persist.ark.mem_config_property", "");
156 size_t gcThreadNum = OHOS::system::GetUintParameter<size_t>("persist.ark.gcthreads", 7);
157 size_t longPauseTime = OHOS::system::GetUintParameter<size_t>("persist.ark.longpausetime", 40);
158 pandaOption.SetArkProperties(arkProperties);
159 pandaOption.SetArkBundleName(bundleName);
160 pandaOption.SetMemConfigProperty(memConfigProperty);
161 pandaOption.SetGcThreadNum(gcThreadNum);
162 pandaOption.SetLongPauseTime(longPauseTime);
163 TAG_LOGI(AAFwkTag::JSRUNTIME, "ark properties = %{public}d bundleName = %{public}s",
164 arkProperties, bundleName.c_str());
165 pandaOption.SetGcType(panda::RuntimeOption::GC_TYPE::GEN_GC);
166 pandaOption.SetGcPoolSize(DEFAULT_GC_POOL_SIZE);
167 pandaOption.SetLogLevel(panda::RuntimeOption::LOG_LEVEL::FOLLOW);
168 pandaOption.SetLogBufPrint(PrintVmLog);
169
170 bool asmInterpreterEnabled = OHOS::system::GetBoolParameter("persist.ark.asminterpreter", true);
171 std::string asmOpcodeDisableRange = OHOS::system::GetParameter("persist.ark.asmopcodedisablerange", "");
172 pandaOption.SetEnableAsmInterpreter(asmInterpreterEnabled);
173 pandaOption.SetAsmOpcodeDisableRange(asmOpcodeDisableRange);
174 pandaOption.SetEnableJIT(options.jitEnabled);
175
176 bool useAbilityRuntime = (options.isStageModel) || (options.isTestFramework);
177 if (useAbilityRuntime) {
178 bool aotEnabled = OHOS::system::GetBoolParameter("persist.ark.aot", true);
179 pandaOption.SetEnableAOT(aotEnabled);
180 pandaOption.SetProfileDir(SANDBOX_ARK_PROIFILE_PATH);
181 }
182
183 OHOSJsEnvLogger::RegisterJsEnvLogger();
184 // options eventRunner is nullptr
185 jsEnv = std::make_shared<JsEnv::JsEnvironment>(std::make_unique<OHOSJsEnvironmentImpl>(options.eventRunner));
186 if (jsEnv == nullptr || !jsEnv->Initialize(pandaOption, static_cast<void*>(this))
187 || jsEnv->GetNativeEngine() == nullptr) {
188 TAG_LOGE(AAFwkTag::JSRUNTIME, "Initialize js environment failed");
189 return napi_status::napi_ok;
190 }
191 jsEnv->GetNativeEngine()->MarkNativeThread();
192 return AddEnv(reinterpret_cast<napi_env>(jsEnv->GetNativeEngine()), jsEnv);
193 }
194
Init(const Options & options,napi_env env)195 napi_status JsRuntimeLite::Init(const Options& options, napi_env env)
196 {
197 auto jsEnv = GetJsEnv(env);
198 if (jsEnv == nullptr) {
199 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv");
200 return napi_status::napi_generic_failure;
201 }
202
203 auto vm = GetEcmaVm(jsEnv);
204 if (!vm) {
205 TAG_LOGE(AAFwkTag::JSRUNTIME, "null vm");
206 return napi_status::napi_generic_failure;
207 }
208
209 bool isModular = false;
210 if (!options.preload) {
211 LoadAotFile(options, jsEnv);
212 panda::JSNApi::SetBundle(vm, options.isBundle);
213 panda::JSNApi::SetBundleName(vm, options.bundleName);
214 panda::JSNApi::SetHostResolveBufferTracker(
215 vm, JsModuleReader(options.bundleName, options.hapPath, options.isUnique));
216 isModular = !panda::JSNApi::IsBundle(vm);
217 panda::JSNApi::SetSearchHapPathTracker(
218 vm, [options](const std::string moduleName, std::string &hapPath) -> bool {
219 if (options.hapModulePath.find(moduleName) == options.hapModulePath.end()) {
220 return false;
221 }
222 hapPath = options.hapModulePath.find(moduleName)->second;
223 return true;
224 });
225 std::map<std::string, std::vector<std::vector<std::string>>> pkgContextInfoMap;
226 std::map<std::string, std::string> pkgAliasMap;
227 GetPkgContextInfoListMap(options.pkgContextInfoJsonStringMap, pkgContextInfoMap, pkgAliasMap);
228 panda::JSNApi::SetpkgContextInfoList(vm, pkgContextInfoMap);
229 panda::JSNApi::SetPkgAliasList(vm, pkgAliasMap);
230 panda::JSNApi::SetPkgNameList(vm, options.packageNameList);
231 }
232
233 if (!preloaded_) {
234 InitConsoleModule(jsEnv);
235 }
236
237 if (!options.preload) {
238 if (!options.isUnique) {
239 InitTimerModule(jsEnv);
240 }
241 InitWorkerModule(options, jsEnv);
242 SetModuleLoadChecker(options.moduleCheckerDelegate, jsEnv);
243 SetRequestAotCallback(jsEnv);
244
245 if (!InitLoop(jsEnv)) {
246 TAG_LOGE(AAFwkTag::JSRUNTIME, "Init loop failed");
247 return napi_status::napi_generic_failure;
248 }
249 }
250
251 preloaded_ = options.preload;
252 return napi_status::napi_ok;
253 }
254
AddEnv(napi_env env,std::shared_ptr<JsEnv::JsEnvironment> jsEnv)255 napi_status JsRuntimeLite::AddEnv(napi_env env, std::shared_ptr<JsEnv::JsEnvironment> jsEnv)
256 {
257 std::lock_guard<std::mutex> lock(envMutex_);
258 pid_t threadId = gettid();
259 if (threadIds_.find(threadId) != threadIds_.end()) {
260 TAG_LOGE(AAFwkTag::JSRUNTIME, "already created");
261 return napi_status::napi_create_ark_runtime_only_one_env_per_thread;
262 }
263 threadIds_.insert(threadId);
264 TAG_LOGD(AAFwkTag::JSRUNTIME, "add threadId %{public}d", threadId);
265 auto it = envMap_.find(env);
266 if (it == envMap_.end()) {
267 envMap_[env] = jsEnv;
268 return napi_status::napi_ok;
269 }
270 return napi_status::napi_generic_failure;
271 }
272
RemoveJsEnv(napi_env env)273 napi_status JsRuntimeLite::RemoveJsEnv(napi_env env)
274 {
275 std::lock_guard<std::mutex> lock(envMutex_);
276 pid_t threadId = gettid();
277 TAG_LOGD(AAFwkTag::JSRUNTIME, "remove threadId %{public}d", threadId);
278 threadIds_.erase(threadId);
279 auto it = envMap_.find(env);
280 if (it != envMap_.end()) {
281 it->second.reset();
282 it->second = nullptr;
283 envMap_.erase(env);
284 return napi_status::napi_ok;
285 }
286 return napi_status::napi_destroy_ark_runtime_env_not_exist;
287 }
288
GetEcmaVm(const std::shared_ptr<JsEnv::JsEnvironment> & jsEnv) const289 panda::ecmascript::EcmaVM* JsRuntimeLite::GetEcmaVm(const std::shared_ptr<JsEnv::JsEnvironment>& jsEnv) const
290 {
291 if (jsEnv == nullptr) {
292 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv");
293 return nullptr;
294 }
295 return jsEnv->GetVM();
296 }
297
GetJsEnv(napi_env env)298 std::shared_ptr<JsEnv::JsEnvironment> JsRuntimeLite::GetJsEnv(napi_env env)
299 {
300 std::lock_guard<std::mutex> lock(envMutex_);
301 auto jsEnv = envMap_.find(env);
302 if (jsEnv != envMap_.end()) {
303 return jsEnv->second;
304 }
305 return nullptr;
306 }
307
LoadAotFile(const Options & options,const std::shared_ptr<JsEnv::JsEnvironment> & jsEnv)308 void JsRuntimeLite::LoadAotFile(const Options& options, const std::shared_ptr<JsEnv::JsEnvironment>& jsEnv)
309 {
310 auto vm = GetEcmaVm(jsEnv);
311 if (!vm || options.hapPath.empty()) {
312 return;
313 }
314
315 bool newCreate = false;
316 std::string loadPath = ExtractorUtil::GetLoadFilePath(options.hapPath);
317 std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor(loadPath, newCreate, true);
318 if (extractor != nullptr && newCreate) {
319 panda::JSNApi::LoadAotFile(vm, options.moduleName);
320 }
321 }
322
InitConsoleModule(const std::shared_ptr<JsEnv::JsEnvironment> & jsEnv)323 void JsRuntimeLite::InitConsoleModule(const std::shared_ptr<JsEnv::JsEnvironment>& jsEnv)
324 {
325 if (jsEnv == nullptr) {
326 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv");
327 return;
328 }
329 jsEnv->InitConsoleModule();
330 }
331
InitTimerModule(const std::shared_ptr<JsEnv::JsEnvironment> & jsEnv)332 void JsRuntimeLite::InitTimerModule(const std::shared_ptr<JsEnv::JsEnvironment>& jsEnv)
333 {
334 if (jsEnv == nullptr) {
335 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv");
336 return;
337 }
338 jsEnv->InitTimerModule();
339 }
340
SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate> & moduleCheckerDelegate,const std::shared_ptr<JsEnv::JsEnvironment> & jsEnv)341 void JsRuntimeLite::SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate>& moduleCheckerDelegate,
342 const std::shared_ptr<JsEnv::JsEnvironment>& jsEnv)
343 {
344 if (jsEnv == nullptr) {
345 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv");
346 return;
347 }
348 jsEnv->SetModuleLoadChecker(moduleCheckerDelegate);
349 }
350
SetRequestAotCallback(const std::shared_ptr<JsEnv::JsEnvironment> & jsEnv)351 void JsRuntimeLite::SetRequestAotCallback(const std::shared_ptr<JsEnv::JsEnvironment>& jsEnv)
352 {
353 if (jsEnv == nullptr) {
354 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv");
355 return;
356 }
357 auto callback = [](const std::string& bundleName, const std::string& moduleName, int32_t triggerMode) -> int32_t {
358 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
359 if (systemAbilityMgr == nullptr) {
360 TAG_LOGE(AAFwkTag::JSRUNTIME, "null SaMgr");
361 return ERR_INVALID_VALUE;
362 }
363
364 auto remoteObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
365 if (remoteObj == nullptr) {
366 TAG_LOGE(AAFwkTag::JSRUNTIME, "null remoteObj");
367 return ERR_INVALID_VALUE;
368 }
369
370 auto bundleMgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObj);
371 if (bundleMgr == nullptr) {
372 TAG_LOGE(AAFwkTag::JSRUNTIME, "null bms");
373 return ERR_INVALID_VALUE;
374 }
375
376 TAG_LOGD(AAFwkTag::JSRUNTIME,
377 "Reset compile status, bundleName: %{public}s, moduleName: %{public}s, triggerMode: %{public}d",
378 bundleName.c_str(), moduleName.c_str(), triggerMode);
379 return bundleMgr->ResetAOTCompileStatus(bundleName, moduleName, triggerMode);
380 };
381
382 jsEnv->SetRequestAotCallback(callback);
383 }
384
InitLoop(const std::shared_ptr<JsEnv::JsEnvironment> & jsEnv)385 bool JsRuntimeLite::InitLoop(const std::shared_ptr<JsEnv::JsEnvironment>& jsEnv)
386 {
387 if (jsEnv == nullptr) {
388 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv");
389 return false;
390 }
391 return jsEnv->InitLoop();
392 }
393
InitWorkerModule(const Options & options,const std::shared_ptr<JsEnv::JsEnvironment> & jsEnv)394 void JsRuntimeLite::InitWorkerModule(const Options& options, const std::shared_ptr<JsEnv::JsEnvironment>& jsEnv)
395 {
396 if (jsEnv == nullptr) {
397 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv");
398 return;
399 }
400
401 std::shared_ptr<JsEnv::WorkerInfo> workerInfo = std::make_shared<JsEnv::WorkerInfo>();
402 workerInfo->codePath = panda::panda_file::StringPacProtect(options.codePath);
403 workerInfo->isDebugVersion = options.isDebugVersion;
404 workerInfo->isBundle = options.isBundle;
405 workerInfo->packagePathStr = options.packagePathStr;
406 workerInfo->assetBasePathStr = options.assetBasePathStr;
407 workerInfo->hapPath = panda::panda_file::StringPacProtect(options.hapPath);
408 workerInfo->isStageModel = panda::panda_file::BoolPacProtect(options.isStageModel);
409 workerInfo->moduleName = options.moduleName;
410 if (options.isJsFramework) {
411 SetJsFramework();
412 }
413 jsEnv->InitWorkerModule(workerInfo);
414 }
415
SetChildOptions(const Options & options)416 void JsRuntimeLite::SetChildOptions(const Options& options)
417 {
418 std::lock_guard<std::mutex> lock(childOptionsMutex_);
419 if (childOptions_ == nullptr) {
420 childOptions_ = std::make_shared<Options>();
421 }
422 childOptions_->lang = options.lang;
423 childOptions_->bundleName = options.bundleName;
424 childOptions_->moduleName = options.moduleName;
425 childOptions_->codePath = options.codePath;
426 childOptions_->bundleCodeDir = options.bundleCodeDir;
427 childOptions_->hapPath = options.hapPath;
428 childOptions_->arkNativeFilePath = options.arkNativeFilePath;
429 childOptions_->hapModulePath = options.hapModulePath;
430 childOptions_->loadAce = options.loadAce;
431 childOptions_->preload = options.preload;
432 childOptions_->isBundle = options.isBundle;
433 childOptions_->isDebugVersion = options.isDebugVersion;
434 childOptions_->isJsFramework = options.isJsFramework;
435 childOptions_->isStageModel = options.isStageModel;
436 childOptions_->isTestFramework = options.isTestFramework;
437 childOptions_->uid = options.uid;
438 childOptions_->isUnique = options.isUnique;
439 childOptions_->moduleCheckerDelegate = options.moduleCheckerDelegate;
440 childOptions_->apiTargetVersion = options.apiTargetVersion;
441 childOptions_->packagePathStr = options.packagePathStr;
442 childOptions_->assetBasePathStr = options.assetBasePathStr;
443 childOptions_->jitEnabled = options.jitEnabled;
444 childOptions_->pkgContextInfoJsonStringMap = options.pkgContextInfoJsonStringMap;
445 childOptions_->packageNameList = options.packageNameList;
446 childOptions_->versionCode = options.versionCode;
447 }
448
GetChildOptions()449 std::shared_ptr<Options> JsRuntimeLite::GetChildOptions()
450 {
451 std::lock_guard<std::mutex> lock(childOptionsMutex_);
452 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
453 return childOptions_;
454 }
455
GetPkgContextInfoListMap(const std::map<std::string,std::string> & contextInfoMap,std::map<std::string,std::vector<std::vector<std::string>>> & pkgContextInfoMap,std::map<std::string,std::string> & pkgAliasMap)456 void JsRuntimeLite::GetPkgContextInfoListMap(const std::map<std::string, std::string> &contextInfoMap,
457 std::map<std::string, std::vector<std::vector<std::string>>> &pkgContextInfoMap,
458 std::map<std::string, std::string> &pkgAliasMap)
459 {
460 for (auto it = contextInfoMap.begin(); it != contextInfoMap.end(); it++) {
461 std::vector<std::vector<std::string>> pkgContextInfoList;
462 std::string filePath = it->second;
463 bool newCreate = false;
464 std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor(
465 ExtractorUtil::GetLoadFilePath(filePath), newCreate, false);
466 if (!extractor) {
467 TAG_LOGE(AAFwkTag::JSRUNTIME, "moduleName: %{public}s load hapPath failed", it->first.c_str());
468 continue;
469 }
470 std::unique_ptr<uint8_t[]> data;
471 size_t dataLen = 0;
472 if (!extractor->ExtractToBufByName("pkgContextInfo.json", data, dataLen)) {
473 TAG_LOGD(AAFwkTag::JSRUNTIME, "moduleName: %{public}s get pkgContextInfo failed", it->first.c_str());
474 continue;
475 }
476 auto jsonObject = nlohmann::json::parse(data.get(), data.get() + dataLen, nullptr, false);
477 if (jsonObject.is_discarded()) {
478 TAG_LOGE(AAFwkTag::JSRUNTIME, "moduleName: %{public}s parse json error", it->first.c_str());
479 continue;
480 }
481 ParsePkgContextInfoJson(jsonObject, pkgContextInfoList, pkgAliasMap);
482 TAG_LOGD(AAFwkTag::JSRUNTIME, "moduleName: %{public}s parse json success", it->first.c_str());
483 pkgContextInfoMap[it->first] = pkgContextInfoList;
484 }
485 }
486
ParsePkgContextInfoJson(nlohmann::json & jsonObject,std::vector<std::vector<std::string>> & pkgContextInfoList,std::map<std::string,std::string> & pkgAliasMap)487 void JsRuntimeLite::ParsePkgContextInfoJson(nlohmann::json &jsonObject,
488 std::vector<std::vector<std::string>> &pkgContextInfoList, std::map<std::string, std::string> &pkgAliasMap)
489 {
490 for (nlohmann::json::iterator jsonIt = jsonObject.begin(); jsonIt != jsonObject.end(); jsonIt++) {
491 std::vector<std::string> items;
492 items.emplace_back(jsonIt.key());
493 nlohmann::json itemObject = jsonIt.value();
494 std::string pkgName = "";
495 items.emplace_back(PACKAGE_NAME);
496 if (itemObject[PACKAGE_NAME].is_null() || !itemObject[PACKAGE_NAME].is_string()) {
497 items.emplace_back(pkgName);
498 } else {
499 pkgName = itemObject[PACKAGE_NAME].get<std::string>();
500 items.emplace_back(pkgName);
501 }
502
503 ParsePkgContextInfoJsonString(itemObject, BUNDLE_NAME, items);
504 ParsePkgContextInfoJsonString(itemObject, MODULE_NAME, items);
505 ParsePkgContextInfoJsonString(itemObject, VERSION, items);
506 ParsePkgContextInfoJsonString(itemObject, ENTRY_PATH, items);
507 items.emplace_back(IS_SO);
508 if (itemObject[IS_SO].is_null() || !itemObject[IS_SO].is_boolean()) {
509 items.emplace_back("false");
510 } else {
511 bool isSo = itemObject[IS_SO].get<bool>();
512 if (isSo) {
513 items.emplace_back("true");
514 } else {
515 items.emplace_back("false");
516 }
517 }
518 if (!itemObject[DEPENDENCY_ALIAS].is_null() && itemObject[DEPENDENCY_ALIAS].is_string()) {
519 std::string pkgAlias = itemObject[DEPENDENCY_ALIAS].get<std::string>();
520 if (!pkgAlias.empty()) {
521 pkgAliasMap[pkgAlias] = pkgName;
522 }
523 }
524 pkgContextInfoList.emplace_back(items);
525 }
526 }
527
ParsePkgContextInfoJsonString(const nlohmann::json & itemObject,const std::string & key,std::vector<std::string> & items)528 void JsRuntimeLite::ParsePkgContextInfoJsonString(
529 const nlohmann::json &itemObject, const std::string &key, std::vector<std::string> &items)
530 {
531 items.emplace_back(key);
532 if (itemObject[key].is_null() || !itemObject[key].is_string()) {
533 items.emplace_back("");
534 } else {
535 items.emplace_back(itemObject[key].get<std::string>());
536 }
537 }
538 } // namespace AbilityRuntime
539 } // namespace OHOS