• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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