• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "ohos_resource_adapter_impl.h"
17 
18 #include <ctime>
19 #include <securec.h>
20 #include <sstream>
21 #include <cerrno>
22 #include <cstring>
23 #include <unistd.h>
24 #include <vector>
25 #include <fstream>
26 #include <json/json.h>
27 
28 #include "application_context.h"
29 #include "bundle_mgr_proxy.h"
30 #include "extractor.h"
31 #include "if_system_ability_manager.h"
32 #include "iservice_registry.h"
33 #include "locale_config.h"
34 #include "nweb_log.h"
35 #include "ohos_adapter_helper.h"
36 #include "parameter.h"
37 #include "parameters.h"
38 #include "system_ability_definition.h"
39 
40 using namespace OHOS::AbilityBase;
41 
42 namespace {
43 const std::string NWEB_HAP_PATH = "/system/app/com.ohos.nweb/NWeb.hap";
44 const std::string NWEB_HAP_PATH_1 = "/system/app/NWeb/NWeb.hap";
45 const std::string ARKWEBCORE_HAP_SANDBOX_PATH = "/data/storage/el1/bundle/nweb/entry.hap";
46 const std::string PERSIST_ARKWEBCORE_INSTALL_PATH = "persist.arkwebcore.install_path";
47 const std::string NWEB_HAP_PATH_MODULE_UPDATE = "/module_update/ArkWebCore/app/com.ohos.nweb/NWeb.hap";
48 const std::string HAP_REAL_PATH_PREFIX = "/data/app/el1/bundle/public/";
49 const std::string HAP_SANDBOX_PATH_PREFIX = "/data/storage/el1/bundle/nweb/";
50 const std::string NWEB_BUNDLE_NAME = "com.ohos.nweb";
51 const std::string NWEB_PACKAGE = "entry";
52 const std::string RAWFILE_PREFIX = "resources/rawfile/";
53 const std::string BUNDLE_NAME_PREFIX = "bundleName:";
54 const std::string MODULE_NAME_PREFIX = "moduleName:";
55 constexpr uint32_t TM_YEAR_BITS = 9;
56 constexpr uint32_t TM_MON_BITS = 5;
57 constexpr uint32_t TM_MIN_BITS = 5;
58 constexpr uint32_t TM_HOUR_BITS = 11;
59 constexpr uint32_t START_YEAR = 1900;
60 } // namespace
61 
62 namespace OHOS::NWeb {
63 namespace {
GetResourceMgr(const std::string & bundleName,const std::string & moduleName)64 std::shared_ptr<Global::Resource::ResourceManager> GetResourceMgr(
65     const std::string& bundleName, const std::string& moduleName)
66 {
67     std::shared_ptr<AbilityRuntime::ApplicationContext> context =
68         AbilityRuntime::ApplicationContext::GetApplicationContext();
69     if (!context) {
70         WVLOG_E("Failed to get application context.");
71         return nullptr;
72     }
73 
74     if (bundleName.empty() || moduleName.empty()) {
75         return context->GetResourceManager();
76     }
77     auto moduleContext = context->CreateModuleContext(bundleName, moduleName);
78     if (!moduleContext) {
79         WVLOG_E("Failed to crate module context, bundleName: %{public}s, moduleName: %{public}s.",
80             bundleName.c_str(), moduleName.c_str());
81         return nullptr;
82     }
83     return moduleContext->GetResourceManager();
84 }
85 
ParseRawFile(const std::string & rawFile,std::string & bundleName,std::string & moduleName,std::string & fileName)86 bool ParseRawFile(const std::string& rawFile,
87     std::string& bundleName, std::string& moduleName, std::string& fileName)
88 {
89     if (rawFile.substr(0, RAWFILE_PREFIX.size()) != RAWFILE_PREFIX) {
90         WVLOG_D("ParseRawFile failed, rawfile: %{public}s", rawFile.c_str());
91         return false;
92     }
93 
94     std::string subStr = rawFile.substr(RAWFILE_PREFIX.size());
95     if (subStr.substr(0, BUNDLE_NAME_PREFIX.size()) != BUNDLE_NAME_PREFIX) {
96         return false;
97     }
98     subStr = subStr.substr(BUNDLE_NAME_PREFIX.size());
99     size_t pos = subStr.find('/');
100     if (pos == std::string::npos) {
101         WVLOG_D("ParseRawFile bundleName failed, rawfile: %{public}s", rawFile.c_str());
102         return false;
103     }
104     bundleName = subStr.substr(0, pos);
105 
106     subStr = subStr.substr(pos + 1);
107     if (subStr.substr(0, MODULE_NAME_PREFIX.size()) != MODULE_NAME_PREFIX) {
108         return false;
109     }
110     subStr = subStr.substr(MODULE_NAME_PREFIX.size());
111     pos = subStr.find('/');
112     if (pos == std::string::npos) {
113         WVLOG_D("ParseRawFile moduleName failed, rawfile: %{public}s", rawFile.c_str());
114         return false;
115     }
116     moduleName = subStr.substr(0, pos);
117 
118     fileName = subStr.substr(pos + 1);
119     if (fileName.empty()) {
120         WVLOG_D("ParseRawFile fileName failed, rawfile: %{public}s", rawFile.c_str());
121         return false;
122     }
123     return true;
124 }
125 
convertToSandboxPath(const std::string & installPath,const std::string & prefixPath)126 std::string convertToSandboxPath(const std::string& installPath, const std::string& prefixPath)
127 {
128     if (installPath.empty()) {
129         return "";
130     }
131     size_t result = installPath.find(HAP_REAL_PATH_PREFIX);
132     if (result != std::string::npos) {
133         size_t pos = installPath.find_last_of('/');
134         if (pos != std::string::npos && pos != installPath.size() - 1) {
135             return prefixPath + installPath.substr(pos + 1);
136         }
137     }
138     return installPath;
139 }
140 
GetArkWebHapPath(const std::string & arkWebCoreHapPathOverride,std::vector<std::pair<std::string,int>> & errorMessage)141 std::string GetArkWebHapPath(const std::string& arkWebCoreHapPathOverride,
142                              std::vector<std::pair<std::string, int>>& errorMessage)
143 {
144     std::string prefixPath = WEBVIEW_SANDBOX_PATH;
145     if (access(arkWebCoreHapPathOverride.c_str(), F_OK) == 0) {
146         std::string sandboxPath = convertToSandboxPath(arkWebCoreHapPathOverride, prefixPath);
147         if (access(sandboxPath.c_str(), F_OK) == 0) {
148             WVLOG_D("eixt HAP_arkWebCoreHapPathOverride");
149             return sandboxPath;
150         }
151     }
152     errorMessage.emplace_back("access arkWebCoreHapPathOverride path failed", errno);
153 
154     std::string installPath = convertToSandboxPath(
155         OHOS::system::GetParameter(PERSIST_ARKWEBCORE_INSTALL_PATH, ""), prefixPath);
156     if (access(installPath.c_str(), F_OK) == 0) {
157         WVLOG_D("exit install_path,%{public}s", installPath.c_str());
158         return installPath;
159     }
160     errorMessage.emplace_back("access nweb install path failed", errno);
161 
162     if (access(WEBVIEW_SANDBOX_HAP_PATH, F_OK) == 0) {
163         WVLOG_D("exit WEBVIEW_SANDBOX_HAP_PATH");
164         return WEBVIEW_SANDBOX_HAP_PATH;
165     }
166     errorMessage.emplace_back("access arkwebcore hap sandbox path failed", errno);
167     if (access(WEBVIEW_APP_HAP_PATH2, F_OK) == 0) {
168         WVLOG_D("exit WEBVIEW_APP_HAP_PATH2");
169         return WEBVIEW_APP_HAP_PATH2;
170     }
171     errorMessage.emplace_back("access ohos nweb hap path failed", errno);
172     if (access(WEBVIEW_APP_HAP_PATH, F_OK) == 0) {
173         WVLOG_D("exit WEBVIEW_APP_HAP_PATH");
174         return WEBVIEW_APP_HAP_PATH;
175     }
176     errorMessage.emplace_back("access nweb hap path failed", errno);
177     if (access(WEBVIEW_HAP_PATH, F_OK) == 0) {
178         WVLOG_D("exit WEBVIEW_HAP_PATH");
179         return WEBVIEW_HAP_PATH;
180     }
181     errorMessage.emplace_back("access nweb hap module update path failed", errno);
182     return "";
183 }
184 
GetNWebHapPath(const std::string & arkWebCoreHapPathOverride)185 std::string GetNWebHapPath(const std::string& arkWebCoreHapPathOverride)
186 {
187     std::vector<std::pair<std::string, int>> errorMessage;
188     std::string arkWebHapPath = GetArkWebHapPath(arkWebCoreHapPathOverride, errorMessage);
189     if (!arkWebHapPath.empty()) {
190         return arkWebHapPath;
191     }
192 
193     std::string prefixPath = HAP_SANDBOX_PATH_PREFIX;
194     if (access(arkWebCoreHapPathOverride.c_str(), F_OK) == 0) {
195         WVLOG_D("eixt HAP_arkWebCoreHapPathOverride");
196         std::string sandboxPath = convertToSandboxPath(arkWebCoreHapPathOverride, prefixPath);
197         WVLOG_D("sandboxPath,%{public}s", sandboxPath.c_str());
198         if (access(sandboxPath.c_str(), F_OK) == 0) {
199             return sandboxPath;
200         }
201     }
202     errorMessage.emplace_back("access arkWebCoreHapPathOverride path failed", errno);
203 
204     std::string installPath = convertToSandboxPath(
205         OHOS::system::GetParameter(PERSIST_ARKWEBCORE_INSTALL_PATH, ""), prefixPath);
206     WVLOG_D("install_path,%{public}s", installPath.c_str());
207     if (access(installPath.c_str(), F_OK) == 0) {
208         return installPath;
209     }
210     errorMessage.emplace_back("access nweb install path failed", errno);
211 
212     if (access(ARKWEBCORE_HAP_SANDBOX_PATH.c_str(), F_OK) == 0) {
213         WVLOG_D("eixt ARKWEBCORE_HAP_SANDBOX_PATH");
214         return ARKWEBCORE_HAP_SANDBOX_PATH;
215     }
216     errorMessage.emplace_back("access arkwebcore hap sandbox path failed", errno);
217 
218     if (access(NWEB_HAP_PATH.c_str(), F_OK) == 0) {
219         WVLOG_D("eixt NWEB_HAP_PATH");
220         return NWEB_HAP_PATH;
221     }
222     if (access(NWEB_HAP_PATH_1.c_str(), F_OK) == 0) {
223         WVLOG_D("eixt NWEB_HAP_PATH_1");
224         return NWEB_HAP_PATH_1;
225     }
226     if (access(NWEB_HAP_PATH_MODULE_UPDATE.c_str(), F_OK) == 0) {
227         WVLOG_D("eixt NWEB_HAP_PATH_MODULE_UPDATE");
228         return NWEB_HAP_PATH_MODULE_UPDATE;
229     }
230     return "";
231 }
232 } // namespace
233 
OhosFileMapperImpl(std::unique_ptr<OHOS::AbilityBase::FileMapper> fileMap,const std::shared_ptr<Extractor> & extractor)234 OhosFileMapperImpl::OhosFileMapperImpl(std::unique_ptr<OHOS::AbilityBase::FileMapper> fileMap,
235     const std::shared_ptr<Extractor>& extractor): extractor_(extractor), fileMap_(std::move(fileMap))
236 {
237 }
238 
GetFd()239 int32_t OhosFileMapperImpl::GetFd()
240 {
241     return -1;
242 }
243 
GetOffset()244 int32_t OhosFileMapperImpl::GetOffset()
245 {
246     return fileMap_ ? fileMap_->GetOffset(): -1;
247 }
248 
GetFileName()249 std::string OhosFileMapperImpl::GetFileName()
250 {
251     return fileMap_ ? fileMap_->GetFileName(): "";
252 }
253 
IsCompressed()254 bool OhosFileMapperImpl::IsCompressed()
255 {
256     return fileMap_ ? fileMap_->IsCompressed(): false;
257 }
258 
GetDataPtr()259 void* OhosFileMapperImpl::GetDataPtr()
260 {
261     return fileMap_ ? fileMap_->GetDataPtr(): nullptr;
262 }
263 
GetDataLen()264 size_t OhosFileMapperImpl::GetDataLen()
265 {
266     return fileMap_ ? fileMap_->GetDataLen(): 0;
267 }
268 
UnzipData(uint8_t ** dest,size_t & len)269 bool OhosFileMapperImpl::UnzipData(uint8_t** dest, size_t& len)
270 {
271     if (extractor_ && IsCompressed()) {
272         std::unique_ptr<uint8_t[]> data;
273         bool result = extractor_->UnzipData(std::move(fileMap_), data, len);
274         if (result) {
275             *dest = data.release();
276         }
277         return result;
278     }
279     return false;
280 }
281 
282 std::string OhosResourceAdapterImpl::arkWebCoreHapPathOverride_ = "";
OhosResourceAdapterImpl(const std::string & hapPath)283 OhosResourceAdapterImpl::OhosResourceAdapterImpl(const std::string& hapPath)
284 {
285     Init(hapPath);
286 }
287 
Init(const std::string & hapPath)288 void OhosResourceAdapterImpl::Init(const std::string& hapPath)
289 {
290     bool newCreate = false;
291     std::string nwebHapPath = GetNWebHapPath(arkWebCoreHapPathOverride_);
292     if (!nwebHapPath.empty()) {
293         sysExtractor_ = ExtractorUtil::GetExtractor(nwebHapPath, newCreate);
294         if (!sysExtractor_) {
295             WVLOG_E("RuntimeExtractor create failed for %{public}s", nwebHapPath.c_str());
296         }
297     }
298     if (hapPath.empty()) {
299         return;
300     }
301     std::string loadPath = ExtractorUtil::GetLoadFilePath(hapPath);
302     extractor_ = ExtractorUtil::GetExtractor(loadPath, newCreate);
303     if (!extractor_) {
304         WVLOG_E("RuntimeExtractor create failed for %{public}s", hapPath.c_str());
305     }
306 }
307 
GetRawFileData(const std::string & rawFile,size_t & len,uint8_t ** dest,bool isSys)308 bool OhosResourceAdapterImpl::GetRawFileData(const std::string& rawFile, size_t& len,
309     uint8_t** dest, bool isSys)
310 {
311     std::unique_ptr<uint8_t[]> data;
312     bool result;
313     if (isSys) {
314         result =  GetRawFileData(sysExtractor_, rawFile, len, data);
315         if (result) {
316             *dest = data.release();
317         }
318         return result;
319     }
320     std::string bundleName;
321     std::string moduleName;
322     std::string fileName;
323     if (ParseRawFile(rawFile, bundleName, moduleName, fileName)) {
324         auto resourceManager = GetResourceMgr(bundleName, moduleName);
325         if (!resourceManager) {
326             result = GetRawFileData(extractor_, rawFile, len, data);
327             if (result) {
328                 *dest = data.release();
329             }
330             return result;
331         }
332         auto state = resourceManager->GetRawFileFromHap(fileName, len, data);
333         if (state != Global::Resource::SUCCESS) {
334             WVLOG_E("GetRawFileFromHap failed, state: %{public}d, fileName: %{public}s", state, fileName.c_str());
335             result = GetRawFileData(extractor_, rawFile, len, data);
336             if (result) {
337                 *dest = data.release();
338             }
339             return result;
340         }
341         *dest = data.release();
342         return true;
343     }
344 
345     result = GetRawFileData(extractor_, rawFile, len, data);
346     if (result) {
347         *dest = data.release();
348     }
349     return result;
350 }
351 
GetResourceString(const std::string & bundleName,const std::string & moduleName,const int32_t resId,std::string & result)352 bool OhosResourceAdapterImpl::GetResourceString(const std::string& bundleName,
353     const std::string& moduleName, const int32_t resId, std::string& result)
354 {
355     auto resourceManager = GetResourceMgr(bundleName, moduleName);
356     if (!resourceManager) {
357         return false;
358     }
359     if (resourceManager->GetStringById(resId, result) == Global::Resource::SUCCESS) {
360         return true;
361     }
362     return false;
363 }
364 
GetRawFileMapper(const std::string & rawFile,bool isSys)365 std::shared_ptr<OhosFileMapper> OhosResourceAdapterImpl::GetRawFileMapper(const std::string& rawFile,
366     bool isSys)
367 {
368     return GetRawFileMapper(isSys? sysExtractor_: extractor_, rawFile);
369 }
370 
IsRawFileExist(const std::string & rawFile,bool isSys)371 bool OhosResourceAdapterImpl::IsRawFileExist(const std::string& rawFile, bool isSys)
372 {
373     return HasEntry(isSys? sysExtractor_: extractor_, rawFile);
374 }
375 
GetRawFileLastModTime(const std::string & rawFile,uint16_t & date,uint16_t & time,bool isSys)376 bool OhosResourceAdapterImpl::GetRawFileLastModTime(const std::string& rawFile,
377     uint16_t& date, uint16_t& time, bool isSys)
378 {
379     FileInfo info;
380     if (GetFileInfo(isSys? sysExtractor_: extractor_, rawFile, info)) {
381         date = info.lastModDate;
382         time = info.lastModTime;
383         return true;
384     }
385     return false;
386 }
387 
GetRawFileLastModTime(const std::string & rawFile,time_t & time,bool isSys)388 bool OhosResourceAdapterImpl::GetRawFileLastModTime(const std::string& rawFile, time_t& time, bool isSys)
389 {
390     FileInfo info;
391     if (GetFileInfo(isSys? sysExtractor_: extractor_, rawFile, info)) {
392         uint16_t modifiedDate = info.lastModDate;
393         uint16_t modifiedTime = info.lastModTime;
394         struct tm newTime;
395         newTime.tm_year = ((modifiedDate >> TM_YEAR_BITS) & 0x7f) + START_YEAR;
396         newTime.tm_mon = (modifiedDate >> TM_MON_BITS) & 0xf;
397         newTime.tm_mday = modifiedDate & 0x1f;
398         newTime.tm_hour = (modifiedTime >> TM_HOUR_BITS) & 0x1f;
399         newTime.tm_min = (modifiedTime >> TM_MIN_BITS) & 0x2f;
400         newTime.tm_sec = (modifiedTime << 1) & 0x1f;
401         newTime.tm_isdst = 0;
402         time = mktime(&newTime);
403         return true;
404     }
405     return false;
406 }
407 
408 // static
HasEntry(const std::shared_ptr<OHOS::AbilityBase::Extractor> & manager,const std::string & rawFile)409 bool OhosResourceAdapterImpl::HasEntry(const std::shared_ptr<OHOS::AbilityBase::Extractor>& manager,
410     const std::string& rawFile)
411 {
412     if (!manager) {
413         return false;
414     }
415     return manager->HasEntry(rawFile);
416 }
417 
GetFileInfo(const std::shared_ptr<OHOS::AbilityBase::Extractor> & manager,const std::string & rawFile,OHOS::AbilityBase::FileInfo & info)418 bool OhosResourceAdapterImpl::GetFileInfo(const std::shared_ptr<OHOS::AbilityBase::Extractor>& manager,
419     const std::string& rawFile, OHOS::AbilityBase::FileInfo& info)
420 {
421     if (!manager) {
422         return false;
423     }
424     return manager->GetFileInfo(rawFile, info);
425 }
426 
GetModuleName(const char * configStr,size_t len)427 std::string OhosResourceAdapterImpl::GetModuleName(const char *configStr, size_t len)
428 {
429     if (configStr == nullptr) {
430         return std::string();
431     }
432     std::string config(configStr, len);
433     static const char *key = "\"moduleName\"";
434     auto idx = config.find(key);
435     if (idx == std::string::npos) {
436         return std::string();
437     }
438     auto start = config.find("\"", idx + strlen(key));
439     if (start == std::string::npos) {
440         return std::string();
441     }
442     auto end = config.find("\"", start + 1);
443     if (end == std::string::npos || end < start + 1) {
444         return std::string();
445     }
446 
447     std::string retStr = std::string(configStr + start + 1, end - start - 1);
448     return retStr;
449 }
450 
ParseModuleName(const std::shared_ptr<Extractor> & manager)451 std::string OhosResourceAdapterImpl::ParseModuleName(const std::shared_ptr<Extractor> &manager)
452 {
453     if (manager == nullptr) {
454         return std::string();
455     }
456     std::unique_ptr<uint8_t[]> configBuf;
457     size_t len;
458     bool ret = manager->ExtractToBufByName("config.json", configBuf, len);
459     if (!ret) {
460         WVLOG_E("failed to get config data from ability");
461         return std::string();
462     }
463     // parse config.json
464     std::string mName = GetModuleName(reinterpret_cast<char *>(configBuf.get()), len);
465     if (mName.size() == 0) {
466         WVLOG_E("parse moduleName from config.json error");
467         return std::string();
468     }
469     return mName;
470 }
471 
GetRawFileData(const std::shared_ptr<Extractor> & manager,const std::string & rawFile,size_t & len,std::unique_ptr<uint8_t[]> & dest)472 bool OhosResourceAdapterImpl::GetRawFileData(const std::shared_ptr<Extractor>& manager,
473     const std::string& rawFile, size_t& len, std::unique_ptr<uint8_t[]>& dest)
474 {
475     if (!manager) {
476         return false;
477     }
478     if (manager->IsStageModel()) {
479         return manager->ExtractToBufByName(rawFile, dest, len);
480     }
481     std::string moduleName = OhosResourceAdapterImpl::ParseModuleName(manager);
482     std::string rawFilePath("assets/");
483     rawFilePath.append(moduleName);
484     rawFilePath.append("/");
485     rawFilePath.append(rawFile);
486     WVLOG_E("fa filepath:%{public}s", rawFilePath.c_str());
487     return manager->ExtractToBufByName(rawFilePath, dest, len);
488 }
489 
GetRawFileMapper(const std::shared_ptr<OHOS::AbilityBase::Extractor> & manager,const std::string & rawFile)490 std::shared_ptr<OhosFileMapper> OhosResourceAdapterImpl::GetRawFileMapper(
491     const std::shared_ptr<OHOS::AbilityBase::Extractor>& manager,
492     const std::string& rawFile)
493 {
494     if (!manager) {
495         return nullptr;
496     }
497     std::unique_ptr<OHOS::AbilityBase::FileMapper> fileMap;
498     auto& systemPropertiesAdapter = OhosAdapterHelper::GetInstance().GetSystemPropertiesInstance();
499     if (systemPropertiesAdapter.GetWebOptimizationValue()) {
500         fileMap = manager->GetMmapData(rawFile);
501     } else {
502         fileMap = manager->GetData(rawFile);
503     }
504     if (fileMap == nullptr) {
505         return nullptr;
506     }
507     bool isCompressed = fileMap->IsCompressed();
508     return std::make_shared<OhosFileMapperImpl>(std::move(fileMap), isCompressed ? manager: nullptr);
509 }
510 
GetArkWebVersion()511 std::string OhosResourceAdapterImpl::GetArkWebVersion()
512 {
513     const std::string hapPaths[] = {
514         "/module_update/ArkWebCore/app/com.huawei.hmos.arkwebcore/ArkWebCore.hap",
515         "/system/app/com.ohos.arkwebcore/ArkWebCore.hap"
516     };
517     const std::string packInfoPath = "pack.info";
518 
519     for (const auto& hapPath : hapPaths) {
520         OHOS::AbilityBase::Extractor extractor(hapPath);
521         if (!extractor.Init()) {
522             WVLOG_E("Failed to initialize extractor for HAP file: %{public}s", hapPath.c_str());
523             continue;
524         }
525 
526         std::ostringstream contentStream;
527         bool ret = extractor.ExtractByName(packInfoPath, contentStream);
528         if (!ret) {
529             WVLOG_E("Failed to extract pack.info from HAP: %{public}s", hapPath.c_str());
530             continue;
531         }
532 
533         std::string configContent = contentStream.str();
534 
535         Json::Value root;
536         Json::Reader reader;
537         if (!reader.parse(configContent, root)) {
538             WVLOG_E("Failed to parse pack.info from HAP: %{public}s", hapPath.c_str());
539             continue;
540         }
541 
542         if (root.isMember("summary") &&
543             root["summary"].isMember("app") &&
544             root["summary"]["app"].isMember("version") &&
545             root["summary"]["app"]["version"].isMember("name")) {
546             return root["summary"]["app"]["version"]["name"].asString();
547         }
548 
549         WVLOG_E("Version information not found in pack.info from HAP: %{public}s", hapPath.c_str());
550     }
551 
552     WVLOG_E("Failed to get ArkWeb version from any of the specified paths");
553     return "";
554 }
555 
SetArkWebCoreHapPathOverride(const std::string & hapPath)556 void OhosResourceAdapterImpl::SetArkWebCoreHapPathOverride(const std::string& hapPath)
557 {
558     arkWebCoreHapPathOverride_ = hapPath;
559 }
560 
GetSystemLanguage()561 std::string OhosResourceAdapterImpl::GetSystemLanguage()
562 {
563     return OHOS::Global::I18n::LocaleConfig::GetSystemLanguage();
564 }
565 
566 }  // namespace OHOS::NWeb
567