• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 
17 #include <cstdint>
18 #include <dirent.h>
19 #include <dlfcn.h>
20 #include <memory>
21 #include <sys/stat.h>
22 #include <thread>
23 #include <unistd.h>
24 #include <fcntl.h>
25 
26 #include "config_policy_utils.h"
27 #include "nweb_config_helper.h"
28 #include "nweb_log.h"
29 #include "parameters.h"
30 
31 namespace {
32 const std::string WEB_CONFIG_PATH = "etc/web/web_config.xml";
33 const std::string INIT_CONFIG = "initConfig";
34 const std::string DELETE_CONFIG = "deleteArgsConfig";
35 const std::string PERFORMANCE_CONFIG = "performanceConfig";
36 // The config used in base/web/webview
37 const std::string BASE_WEB_CONFIG = "baseWebConfig";
38 const std::string WEB_ANIMATION_DYNAMIC_SETTING_CONFIG = "property_animation_dynamic_settings";
39 const std::string WEB_ANIMATION_DYNAMIC_APP = "dynamic_apps";
40 const std::string WEB_LTPO_STRATEGY = "ltpo_strategy";
41 const auto XML_ATTR_NAME = "name";
42 const auto XML_ATTR_MIN = "min";
43 const auto XML_ATTR_MAX = "max";
44 const auto XML_ATTR_FPS = "preferred_fps";
45 const std::unordered_map<std::string_view, std::function<std::string(std::string&)>> configMap = {
46     { "renderConfig/renderProcessCount",
__anon669529c30202() 47         [](std::string& contentStr) { return std::string("--renderer-process-limit=") + contentStr; } },
48     { "mediaConfig/backgroundMediaShouldSuspend",
__anon669529c30302() 49         [](std::string& contentStr) {
50             return contentStr == "false" ? std::string("--disable-background-media-suspend") : std::string();
51         } },
52     { "loadurlSocPerfConfig/loadurlSocPerfParam",
__anon669529c30402() 53         [](std::string& contentStr) {
54             return contentStr == "true" ? std::string("--ohos-enable-loadurl-soc-perf") : std::string();
55         } },
56     { "mouseWheelSocPerfConfig/mouseWheelSocPerfParam",
__anon669529c30502() 57         [](std::string& contentStr) {
58             return contentStr == "true" ? std::string("--ohos-enable-mousewheel-soc-perf") : std::string();
59         } },
60     { "touchEventConfig/touchEventShouldRegister",
__anon669529c30602() 61         [](std::string& contentStr) {
62             return contentStr == "false" ? std::string("--disable-touch-event-register") : std::string();
63         } },
64     { "settingConfig/enableWaitForUsername",
__anon669529c30702() 65         [](std::string& contentStr) {
66             return contentStr == "true" ? std::string("--ohos-enable-wait-for-username") : std::string();
67         } },
68     { "settingConfig/enableMaxNumberOfSavedFrames",
__anon669529c30802() 69         [](std::string& contentStr) {
70             return contentStr == "true" ? std::string("--ohos-enable-max-number-of-saved-frames") : std::string();
71         } },
72     { "settingConfig/enableNumRasterThreads",
__anon669529c30902() 73         [](std::string& contentStr) {
74             return contentStr == "true" ? std::string("--ohos-enable-num-raster-threads") : std::string();
75         } },
76     { "settingConfig/enableSingleRenderProcess",
__anon669529c30a02() 77         [](std::string& contentStr) {
78             return contentStr == "true" ? std::string("--ohos-enable-single-render-process") : std::string();
79         } },
80     { "userAgentConfig/userAgentValue",
__anon669529c30b02() 81         [](std::string& contentStr) { return std::string("--ohos-user-agent-value=") + contentStr; } },
82     { "settingConfig/enableSimpleBackendIsDefault",
__anon669529c30c02() 83         [](std::string& contentStr) {
84             return contentStr == "true" ? std::string("--ohos-enable-simple-backend-is-default") : std::string();
85         } },
86     { "settingConfig/enableEmbedMode",
__anon669529c30d02() 87         [](std::string& contentStr) {
88             return contentStr == "true" ? std::string("--ohos-enable-embed-mode") : std::string();
89         } },
90     { "settingConfig/enableWebViewImplForLargeScreen",
__anon669529c30e02() 91         [](std::string& contentStr) {
92             return contentStr == "true" ? std::string("--ohos-enable-web-view-impl-for-large-screen") : std::string();
93         } },
94     { "settingConfig/enableDeleteUnusedResourcesDelay",
__anon669529c30f02() 95         [](std::string& contentStr) {
96             return contentStr == "true" ? std::string("--ohos-enable-delete-unused-resources-delay") : std::string();
97         } },
98     { "settingConfig/enableSetHttpCacheMaxSize",
__anon669529c31002() 99         [](std::string& contentStr) {
100             return contentStr == "true" ? std::string("--ohos-enable-set-http-cache-max-size") : std::string();
101         } },
102     { "settingConfig/enableCookieConfigPersistSession",
__anon669529c31102() 103         [](std::string& contentStr) {
104             return contentStr == "true" ? std::string("--ohos-enable-cookie-config-persist-session") : std::string();
105         } },
106     { "settingConfig/enableDoubleTapForPlatform",
__anon669529c31202() 107         [](std::string& contentStr) {
108             return contentStr == "true" ? std::string("--ohos-enable-double-tap-for-platform") : std::string();
109         } },
110     { "settingConfig/enableIgnoreLockdownMode",
__anon669529c31302() 111         [](std::string& contentStr) {
112             return contentStr == "true" ? std::string("--ohos-enable-Ignore-lockdown-mode") : std::string();
113         } },
114     { "settingConfig/enablePrinting",
__anon669529c31402() 115         [](std::string& contentStr) {
116             return contentStr == "true" ? std::string("--ohos-enable-printing") : std::string();
117         } },
118     { "settingConfig/enableHttpCacheSimple",
__anon669529c31502() 119         [](std::string& contentStr) {
120             return contentStr == "true" ? std::string("--ohos-enable-http-cache-simple") : std::string();
121         } },
122     { "settingConfig/enableCalcTabletMode",
__anon669529c31602() 123         [](std::string& contentStr) {
124             return contentStr == "true" ? std::string("--ohos-enable-calc-tablet-mode") : std::string();
125         } },
126     { "outOfProcessGPUConfig/enableOopGpu",
__anon669529c31702() 127         [](std::string& contentStr) {
128             return contentStr == "true" ? std::string("--in-process-gpu") : std::string();
129         } },
130     { "enableVulkanConfig/enableVulkan",
__anon669529c31802() 131         [](std::string& contentStr) {
132             return contentStr == "true" ? std::string("--ohos-enable-vulkan") : std::string();
133         } }
134 };
135 } // namespace
136 
137 namespace OHOS::NWeb {
Instance()138 NWebConfigHelper &NWebConfigHelper::Instance()
139 {
140     static NWebConfigHelper helper;
141     return helper;
142 }
143 
ReadConfigIfNeeded()144 void NWebConfigHelper::ReadConfigIfNeeded()
145 {
146     if (perfConfig_.empty()) {
147         std::shared_ptr<NWebEngineInitArgsImpl> initArgs = std::make_shared<NWebEngineInitArgsImpl>();
148         NWebConfigHelper::Instance().ParseConfig(initArgs);
149     }
150 }
151 
GetConfigPath(const std::string & configFileName)152 std::string NWebConfigHelper::GetConfigPath(const std::string &configFileName)
153 {
154     char buf[PATH_MAX + 1];
155     char *configPath = GetOneCfgFile(configFileName.c_str(), buf, PATH_MAX + 1);
156     char tmpPath[PATH_MAX + 1] = { 0 };
157     if (!configPath || strlen(configPath) == 0 || strlen(configPath) > PATH_MAX || !realpath(configPath, tmpPath)) {
158         WVLOG_I("can not get customization config file");
159         return "/system/" + configFileName;
160     }
161     return std::string(tmpPath);
162 }
163 
ReadConfig(const xmlNodePtr & rootPtr,std::shared_ptr<NWebEngineInitArgsImpl> initArgs)164 void NWebConfigHelper::ReadConfig(const xmlNodePtr &rootPtr, std::shared_ptr<NWebEngineInitArgsImpl> initArgs)
165 {
166     for (xmlNodePtr curNodePtr = rootPtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) {
167         if (curNodePtr->name == nullptr || curNodePtr->type == XML_COMMENT_NODE) {
168             WVLOG_E("invalid node!");
169             continue;
170         }
171         std::string nodeName = reinterpret_cast<const char *>(curNodePtr->name);
172         for (xmlNodePtr curChildNodePtr = curNodePtr->xmlChildrenNode; curChildNodePtr != nullptr;
173             curChildNodePtr = curChildNodePtr->next) {
174             if (curChildNodePtr->name == nullptr || curChildNodePtr->type == XML_COMMENT_NODE) {
175                 WVLOG_E("invalid node!");
176                 continue;
177             }
178             std::string childNodeName = reinterpret_cast<const char *>(curChildNodePtr->name);
179             xmlChar *content = xmlNodeGetContent(curChildNodePtr);
180             if (content == nullptr) {
181                 WVLOG_E("read xml node error: nodeName:(%{public}s)", curChildNodePtr->name);
182                 continue;
183             }
184             std::string contentStr = reinterpret_cast<const char *>(content);
185             xmlFree(content);
186             auto it = configMap.find(nodeName + "/" + childNodeName);
187             if (it == configMap.end()) {
188                 WVLOG_W("not found for web_config: %{public}s/%{public}s", nodeName.c_str(), childNodeName.c_str());
189                 continue;
190             }
191             std::string param = it->second(contentStr);
192             if (!param.empty()) {
193                 initArgs->AddArg(param);
194             }
195         }
196     }
197 }
198 
GetChildrenNode(xmlNodePtr NodePtr,const std::string & childrenNodeName)199 xmlNodePtr NWebConfigHelper::GetChildrenNode(xmlNodePtr NodePtr, const std::string &childrenNodeName)
200 {
201     WVLOG_D("GetChildrenNode:(%{public}s)", childrenNodeName.c_str());
202     for (xmlNodePtr curNodePtr = NodePtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) {
203         if (curNodePtr->name == nullptr || curNodePtr->type == XML_COMMENT_NODE) {
204             WVLOG_E("invalid node!");
205             continue;
206         }
207         if (!xmlStrcmp(curNodePtr->name, reinterpret_cast<const xmlChar*>(childrenNodeName.c_str()))) {
208             return curNodePtr;
209         }
210     }
211     return nullptr;
212 }
213 
ParseConfig(std::shared_ptr<NWebEngineInitArgsImpl> initArgs)214 void NWebConfigHelper::ParseConfig(std::shared_ptr<NWebEngineInitArgsImpl> initArgs)
215 {
216     CfgFiles* cfgFiles = GetCfgFiles(WEB_CONFIG_PATH.c_str());
217     std::string defaultConfigPath = "/system/" + WEB_CONFIG_PATH;
218     if (cfgFiles == nullptr) {
219         WVLOG_E("Not found webConfigxml,read system config");
220         ParseWebConfigXml(defaultConfigPath, initArgs);
221         return;
222     }
223 
224     // When i is 0 ,it means /system/ + WEB_CONFIG_PATH, ignore
225     for (int32_t i = 1; i < MAX_CFG_POLICY_DIRS_CNT; i++) {
226         auto cfgFilePath = cfgFiles->paths[i];
227         if (!cfgFilePath || *(cfgFilePath) == '\0') {
228             break;
229         }
230         WVLOG_D("web config file path:%{public}s", cfgFilePath);
231         if (!cfgFilePath || strlen(cfgFilePath) == 0 || strlen(cfgFilePath) > PATH_MAX) {
232             WVLOG_W("can not get customization config file");
233             ParseWebConfigXml(defaultConfigPath, initArgs);
234             continue;
235         }
236         ParseWebConfigXml(cfgFiles->paths[i], initArgs);
237     }
238     FreeCfgFiles(cfgFiles);
239 }
240 
ParseWebConfigXml(const std::string & configFilePath,std::shared_ptr<NWebEngineInitArgsImpl> initArgs)241 void NWebConfigHelper::ParseWebConfigXml(const std::string& configFilePath,
242     std::shared_ptr<NWebEngineInitArgsImpl> initArgs)
243 {
244     xmlDocPtr docPtr = xmlReadFile(configFilePath.c_str(), nullptr, XML_PARSE_NOBLANKS);
245     if (docPtr == nullptr) {
246         WVLOG_E("load xml error!");
247         return;
248     }
249 
250     xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
251     if (rootPtr == nullptr || rootPtr->name == nullptr ||
252         xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar *>("WEB"))) {
253         WVLOG_E("get root element failed!");
254         xmlFreeDoc(docPtr);
255         return;
256     }
257 
258     xmlNodePtr initNodePtr = GetChildrenNode(rootPtr, INIT_CONFIG);
259     if (initNodePtr != nullptr) {
260         WVLOG_D("read config from init node");
261         ReadConfig(initNodePtr, initArgs);
262     } else {
263         WVLOG_D("read config from root node");
264         ReadConfig(rootPtr, initArgs);
265     }
266 
267     xmlNodePtr deleteNodePtr = GetChildrenNode(rootPtr, DELETE_CONFIG);
268     if (deleteNodePtr != nullptr) {
269         WVLOG_D("read config from delete node");
270         ParseDeleteConfig(deleteNodePtr, initArgs);
271     }
272 
273     if (perfConfig_.empty()) {
274         xmlNodePtr perfNodePtr = GetChildrenNode(rootPtr, PERFORMANCE_CONFIG);
275         if (perfNodePtr != nullptr) {
276             ParsePerfConfig(perfNodePtr);
277         }
278         xmlNodePtr adapterNodePtr = GetChildrenNode(rootPtr, BASE_WEB_CONFIG);
279         if (adapterNodePtr != nullptr) {
280             ParsePerfConfig(adapterNodePtr);
281         }
282     }
283 
284     if (ltpoConfig_.empty() && ltpoStrategy_ == 0) {
285         xmlNodePtr ltpoConfigNodePtr = GetChildrenNode(rootPtr, WEB_ANIMATION_DYNAMIC_SETTING_CONFIG);
286         if (ltpoConfigNodePtr != nullptr) {
287             ParseNWebLTPOConfig(ltpoConfigNodePtr);
288         }
289     }
290     xmlFreeDoc(docPtr);
291 }
292 
ParseNWebLTPOConfig(xmlNodePtr nodePtr)293 void NWebConfigHelper::ParseNWebLTPOConfig(xmlNodePtr nodePtr)
294 {
295     for (xmlNodePtr curNodePtr = nodePtr->xmlChildrenNode; curNodePtr; curNodePtr = curNodePtr->next) {
296         if (curNodePtr->name == nullptr || curNodePtr->type == XML_COMMENT_NODE) {
297             WVLOG_E("invalid node!");
298             continue;
299         }
300         char* namePtr = (char *)xmlGetProp(curNodePtr, BAD_CAST(XML_ATTR_NAME));
301         if (!namePtr) {
302             WVLOG_E("invalid name!");
303             continue;
304         }
305         std::string settingName(namePtr);
306         xmlFree(namePtr);
307         if (settingName == WEB_ANIMATION_DYNAMIC_APP) {
308             ParseNWebLTPOApp(curNodePtr);
309             continue;
310         }
311         if (settingName == WEB_LTPO_STRATEGY) {
312             ParseNWebLTPOStrategy(curNodePtr);
313             continue;
314         }
315         std::vector<FrameRateSetting> frameRateSetting;
316         for (xmlNodePtr curDynamicNodePtr = curNodePtr->xmlChildrenNode; curDynamicNodePtr;
317             curDynamicNodePtr = curDynamicNodePtr->next) {
318             if (curDynamicNodePtr->name == nullptr || curDynamicNodePtr->type == XML_COMMENT_NODE) {
319                 WVLOG_E("invalid node!");
320                 continue;
321             }
322             FrameRateSetting setting;
323             int defaultValue = 0;
324             setting.min_ = safeGetPropAsInt(curDynamicNodePtr, BAD_CAST(XML_ATTR_MIN), defaultValue);
325             setting.max_ = safeGetPropAsInt(curDynamicNodePtr, BAD_CAST(XML_ATTR_MAX), defaultValue);
326             setting.preferredFrameRate_ = safeGetPropAsInt(curDynamicNodePtr, BAD_CAST(XML_ATTR_FPS), defaultValue);
327             if ((setting.max_ >= 0 && setting.min_ >= setting.max_) || setting.preferredFrameRate_ <= 0) {
328                 continue;
329             }
330             frameRateSetting.emplace_back(setting);
331         }
332         ltpoConfig_[settingName] = frameRateSetting;
333     }
334 }
335 
ParseNWebLTPOApp(xmlNodePtr nodePtr)336 void NWebConfigHelper::ParseNWebLTPOApp(xmlNodePtr nodePtr)
337 {
338     for (xmlNodePtr curDynamicNodePtr = nodePtr->xmlChildrenNode; curDynamicNodePtr;
339         curDynamicNodePtr = curDynamicNodePtr->next) {
340         if (curDynamicNodePtr->name == nullptr || curDynamicNodePtr->type == XML_COMMENT_NODE) {
341             WVLOG_E("invalid node!");
342             continue;
343         }
344         std::string bundleName = (char *)xmlGetProp(curDynamicNodePtr, BAD_CAST(XML_ATTR_NAME));
345         ltpoAllowedApps_.emplace(bundleName);
346         WVLOG_D("ltpo dynamic app: %{public}s", bundleName.c_str());
347     }
348 }
349 
ParseNWebLTPOStrategy(xmlNodePtr nodePtr)350 void NWebConfigHelper::ParseNWebLTPOStrategy(xmlNodePtr nodePtr)
351 {
352     ltpoStrategy_ = atoi((char *)xmlNodeGetContent(nodePtr));
353     WVLOG_D("ltpo strategy is: %{public}d", ltpoStrategy_);
354 }
355 
IsLTPODynamicApp(const std::string & bundleName)356 bool NWebConfigHelper::IsLTPODynamicApp(const std::string& bundleName)
357 {
358     return ltpoAllowedApps_.find(bundleName) != ltpoAllowedApps_.end();
359 }
360 
GetLTPOStrategy()361 int32_t NWebConfigHelper::GetLTPOStrategy()
362 {
363     return ltpoStrategy_;
364 }
365 
GetPerfConfig(const std::string & settingName)366 std::vector<FrameRateSetting> NWebConfigHelper::GetPerfConfig(const std::string& settingName)
367 {
368     if (ltpoConfig_.find(settingName) == ltpoConfig_.end()) {
369         WVLOG_E("%{public}s is not exist", settingName.c_str()) ;
370         return {};
371     }
372     return ltpoConfig_[settingName];
373 }
374 
ParsePerfConfig(xmlNodePtr NodePtr)375 void NWebConfigHelper::ParsePerfConfig(xmlNodePtr NodePtr)
376 {
377     WVLOG_D("read performance config");
378     for (xmlNodePtr curNodePtr = NodePtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) {
379         if (curNodePtr->name == nullptr || curNodePtr->type == XML_COMMENT_NODE) {
380             WVLOG_E("invalid node!");
381             continue;
382         }
383         std::string nodeName = reinterpret_cast<const char*>(curNodePtr->name);
384         for (xmlNodePtr curChildNodePtr = curNodePtr->xmlChildrenNode; curChildNodePtr != nullptr;
385              curChildNodePtr = curChildNodePtr->next) {
386             if (curChildNodePtr->name == nullptr || curChildNodePtr->type == XML_COMMENT_NODE) {
387                 WVLOG_E("invalid node!");
388                 continue;
389             }
390             std::string childNodeName = reinterpret_cast<const char*>(curChildNodePtr->name);
391             xmlChar* content = xmlNodeGetContent(curChildNodePtr);
392             if (content == nullptr) {
393                 WVLOG_E("read xml node error: nodeName:(%{public}s)", childNodeName.c_str());
394                 continue;
395             }
396             std::string contentStr = reinterpret_cast<const char*>(content);
397             xmlFree(content);
398             perfConfig_.emplace(nodeName + "/" + childNodeName, contentStr);
399             WriteConfigValueToSysPara(nodeName + "/" + childNodeName, contentStr);
400         }
401     }
402 }
403 
ParsePerfConfig(const std::string & configNodeName,const std::string & argsNodeName)404 std::string NWebConfigHelper::ParsePerfConfig(const std::string &configNodeName, const std::string &argsNodeName)
405 {
406     auto it = perfConfig_.find(configNodeName + "/" + argsNodeName);
407     if (it == perfConfig_.end()) {
408         WVLOG_W("not found perf config for web_config: %{public}s/%{public}s", configNodeName.c_str(),
409                 argsNodeName.c_str());
410         return "";
411     }
412     WVLOG_D("find performance config %{public}s/%{public}s, value is %{public}s.", configNodeName.c_str(),
413         argsNodeName.c_str(), it->second.c_str());
414     return it->second;
415 }
416 
WriteConfigValueToSysPara(const std::string & configName,const std::string & value)417 void NWebConfigHelper::WriteConfigValueToSysPara(const std::string &configName, const std::string &value)
418 {
419     if (configName == "flowBufferConfig/maxFdNumber") {
420         OHOS::system::SetParameter("web.flowbuffer.maxfd", value);
421     }
422 }
423 
ParseDeleteConfig(const xmlNodePtr & rootPtr,std::shared_ptr<NWebEngineInitArgsImpl> initArgs)424 void NWebConfigHelper::ParseDeleteConfig(const xmlNodePtr &rootPtr, std::shared_ptr<NWebEngineInitArgsImpl> initArgs)
425 {
426     for (xmlNodePtr curNodePtr = rootPtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) {
427         if (curNodePtr->name == nullptr || curNodePtr->type == XML_COMMENT_NODE) {
428             WVLOG_E("invalid node!");
429             continue;
430         }
431         std::string nodeName = reinterpret_cast<const char *>(curNodePtr->name);
432         for (xmlNodePtr curChildNodePtr = curNodePtr->xmlChildrenNode; curChildNodePtr != nullptr;
433             curChildNodePtr = curChildNodePtr->next) {
434             if (curChildNodePtr->name == nullptr || curChildNodePtr->type == XML_COMMENT_NODE) {
435                 WVLOG_E("invalid node!");
436                 continue;
437             }
438             std::string childNodeName = reinterpret_cast<const char *>(curChildNodePtr->name);
439             xmlChar *content = xmlNodeGetContent(curChildNodePtr);
440             if (content == nullptr) {
441                 WVLOG_E("read xml node error: nodeName:(%{public}s)", curChildNodePtr->name);
442                 continue;
443             }
444             std::string contentStr = reinterpret_cast<const char *>(content);
445             xmlFree(content);
446             auto it = configMap.find(nodeName + "/" + childNodeName);
447             if (it == configMap.end()) {
448                 WVLOG_W("not found for web_config: %{public}s/%{public}s", nodeName.c_str(), childNodeName.c_str());
449                 continue;
450             }
451             std::string param = it->second(contentStr);
452             if (!param.empty()) {
453                 initArgs->AddDeleteArg(param);
454             }
455         }
456     }
457 }
458 
safeGetPropAsInt(xmlNode * node,const xmlChar * propName,int defaultValue)459 int NWebConfigHelper::safeGetPropAsInt(xmlNode* node, const xmlChar* propName, int defaultValue)
460 {
461     xmlChar* propValue = xmlGetProp(node, propName);
462     int value = (propValue) ? atoi((const char*)propValue) : defaultValue;
463     xmlFree(propValue);
464     return value;
465 }
466 
SetBundleName(const std::string & bundleName)467 void NWebConfigHelper::SetBundleName(const std::string& bundleName)
468 {
469     bundleName_ = bundleName;
470 }
471 
GetBundleName()472 std::string NWebConfigHelper::GetBundleName()
473 {
474     return bundleName_;
475 }
476 
477 } // namespace OHOS::NWeb