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