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 <unistd.h>
22
23 #include "bundle_mgr_proxy.h"
24 #include "if_system_ability_manager.h"
25 #include "iservice_registry.h"
26 #include "nweb_log.h"
27 #include "system_ability_definition.h"
28
29 using namespace OHOS::AbilityBase;
30
31 namespace {
32 const std::string NWEB_HAP_PATH = "/system/app/com.ohos.nweb/NWeb.hap";
33 const std::string NWEB_HAP_PATH_1 = "/system/app/NWeb/NWeb.hap";
34 const std::string NWEB_BUNDLE_NAME = "com.ohos.nweb";
35 const std::string NWEB_PACKAGE = "entry";
36 constexpr uint32_t TM_YEAR_BITS = 9;
37 constexpr uint32_t TM_MON_BITS = 5;
38 constexpr uint32_t TM_MIN_BITS = 5;
39 constexpr uint32_t TM_HOUR_BITS = 11;
40 constexpr uint32_t START_YEAR = 1900;
41 } // namespace
42
43 namespace OHOS::NWeb {
44 namespace {
GetBundleMgrProxy()45 sptr<OHOS::AppExecFwk::BundleMgrProxy> GetBundleMgrProxy()
46 {
47 auto systemAbilityMgr = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
48 if (!systemAbilityMgr) {
49 WVLOG_E("fail to get system ability mgr.");
50 return nullptr;
51 }
52 auto remoteObject = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
53 if (!remoteObject) {
54 WVLOG_E("fail to get bundle manager proxy.");
55 return nullptr;
56 }
57 WVLOG_D("get bundle manager proxy success.");
58 return iface_cast<OHOS::AppExecFwk::BundleMgrProxy>(remoteObject);
59 }
60
GetNWebHapPath()61 std::string GetNWebHapPath()
62 {
63 auto iBundleMgr = GetBundleMgrProxy();
64 if (iBundleMgr) {
65 OHOS::AppExecFwk::AbilityInfo abilityInfo;
66 OHOS::AppExecFwk::HapModuleInfo hapModuleInfo;
67 abilityInfo.bundleName = NWEB_BUNDLE_NAME;
68 abilityInfo.package = NWEB_PACKAGE;
69 if (iBundleMgr->GetHapModuleInfo(abilityInfo, hapModuleInfo)) {
70 WVLOG_D("get hap module info success. %{public}s", hapModuleInfo.hapPath.c_str());
71 return hapModuleInfo.hapPath;
72 }
73 }
74 if (access(NWEB_HAP_PATH.c_str(), F_OK) == 0) {
75 WVLOG_D("eixt NWEB_HAP_PATH");
76 return NWEB_HAP_PATH;
77 }
78 if (access(NWEB_HAP_PATH_1.c_str(), F_OK) == 0) {
79 WVLOG_D("eixt NWEB_HAP_PATH_1");
80 return NWEB_HAP_PATH_1;
81 }
82 WVLOG_E("get nweb hap path failed.");
83 return "";
84 }
85 } // namespace
86
OhosFileMapperImpl(std::unique_ptr<OHOS::AbilityBase::FileMapper> fileMap,const std::shared_ptr<Extractor> & extractor)87 OhosFileMapperImpl::OhosFileMapperImpl(std::unique_ptr<OHOS::AbilityBase::FileMapper> fileMap,
88 const std::shared_ptr<Extractor>& extractor): extractor_(extractor), fileMap_(std::move(fileMap))
89 {
90 }
91
GetFd() const92 int32_t OhosFileMapperImpl::GetFd() const
93 {
94 return -1;
95 }
96
GetOffset() const97 int32_t OhosFileMapperImpl::GetOffset() const
98 {
99 return fileMap_ ? fileMap_->GetOffset(): -1;
100 }
101
GetFileName() const102 std::string OhosFileMapperImpl::GetFileName() const
103 {
104 return fileMap_ ? fileMap_->GetFileName(): "";
105 }
106
IsCompressed() const107 bool OhosFileMapperImpl::IsCompressed() const
108 {
109 return fileMap_ ? fileMap_->IsCompressed(): false;
110 }
111
GetDataPtr() const112 void* OhosFileMapperImpl::GetDataPtr() const
113 {
114 return fileMap_ ? fileMap_->GetDataPtr(): nullptr;
115 }
116
GetDataLen() const117 size_t OhosFileMapperImpl::GetDataLen() const
118 {
119 return fileMap_ ? fileMap_->GetDataLen(): 0;
120 }
121
UnzipData(std::unique_ptr<uint8_t[]> & dest,size_t & len)122 bool OhosFileMapperImpl::UnzipData(std::unique_ptr<uint8_t[]>& dest, size_t& len)
123 {
124 if (extractor_ && IsCompressed()) {
125 return extractor_->UnzipData(std::move(fileMap_), dest, len);
126 }
127 return false;
128 }
129
OhosResourceAdapterImpl(const std::string & hapPath)130 OhosResourceAdapterImpl::OhosResourceAdapterImpl(const std::string& hapPath)
131 {
132 Init(hapPath);
133 }
134
Init(const std::string & hapPath)135 void OhosResourceAdapterImpl::Init(const std::string& hapPath)
136 {
137 bool newCreate = false;
138 std::string nwebHapPath = GetNWebHapPath();
139 if (!nwebHapPath.empty()) {
140 sysExtractor_ = ExtractorUtil::GetExtractor(nwebHapPath, newCreate);
141 if (!sysExtractor_) {
142 WVLOG_E("RuntimeExtractor create failed for %{public}s", nwebHapPath.c_str());
143 }
144 }
145 if (hapPath.empty()) {
146 return;
147 }
148 std::string loadPath = ExtractorUtil::GetLoadFilePath(hapPath);
149 extractor_ = ExtractorUtil::GetExtractor(loadPath, newCreate);
150 if (!extractor_) {
151 WVLOG_E("RuntimeExtractor create failed for %{public}s", hapPath.c_str());
152 }
153 }
154
GetRawFileData(const std::string & rawFile,size_t & len,std::unique_ptr<uint8_t[]> & dest,bool isSys)155 bool OhosResourceAdapterImpl::GetRawFileData(const std::string& rawFile, size_t& len,
156 std::unique_ptr<uint8_t[]>& dest, bool isSys)
157 {
158 return GetRawFileData(isSys? sysExtractor_: extractor_, rawFile, len, dest);
159 }
160
GetRawFileMapper(const std::string & rawFile,std::unique_ptr<OhosFileMapper> & dest,bool isSys)161 bool OhosResourceAdapterImpl::GetRawFileMapper(const std::string& rawFile,
162 std::unique_ptr<OhosFileMapper>& dest, bool isSys)
163 {
164 return GetRawFileMapper(isSys? sysExtractor_: extractor_, rawFile, dest);
165 }
166
IsRawFileExist(const std::string & rawFile,bool isSys)167 bool OhosResourceAdapterImpl::IsRawFileExist(const std::string& rawFile, bool isSys)
168 {
169 return HasEntry(isSys? sysExtractor_: extractor_, rawFile);
170 }
171
GetRawFileLastModTime(const std::string & rawFile,uint16_t & date,uint16_t & time,bool isSys)172 bool OhosResourceAdapterImpl::GetRawFileLastModTime(const std::string& rawFile,
173 uint16_t& date, uint16_t& time, bool isSys)
174 {
175 FileInfo info;
176 if (GetFileInfo(isSys? sysExtractor_: extractor_, rawFile, info)) {
177 date = info.lastModDate;
178 time = info.lastModTime;
179 return true;
180 }
181 return false;
182 }
183
GetRawFileLastModTime(const std::string & rawFile,time_t & time,bool isSys)184 bool OhosResourceAdapterImpl::GetRawFileLastModTime(const std::string& rawFile, time_t& time, bool isSys)
185 {
186 FileInfo info;
187 if (GetFileInfo(isSys? sysExtractor_: extractor_, rawFile, info)) {
188 uint16_t modifiedDate = info.lastModDate;
189 uint16_t modifiedTime = info.lastModTime;
190 struct tm newTime;
191 newTime.tm_year = ((modifiedDate >> TM_YEAR_BITS) & 0x7f) + START_YEAR;
192 newTime.tm_mon = (modifiedDate >> TM_MON_BITS) & 0xf;
193 newTime.tm_mday = modifiedDate & 0x1f;
194 newTime.tm_hour = (modifiedTime >> TM_HOUR_BITS) & 0x1f;
195 newTime.tm_min = (modifiedTime >> TM_MIN_BITS) & 0x2f;
196 newTime.tm_sec = (modifiedTime << 1) & 0x1f;
197 newTime.tm_isdst = 0;
198 time = mktime(&newTime);
199 return true;
200 }
201 return false;
202 }
203
204 // static
HasEntry(const std::shared_ptr<OHOS::AbilityBase::Extractor> & manager,const std::string & rawFile)205 bool OhosResourceAdapterImpl::HasEntry(const std::shared_ptr<OHOS::AbilityBase::Extractor>& manager,
206 const std::string& rawFile)
207 {
208 if (!manager) {
209 return false;
210 }
211 return manager->HasEntry(rawFile);
212 }
213
GetFileInfo(const std::shared_ptr<OHOS::AbilityBase::Extractor> & manager,const std::string & rawFile,OHOS::AbilityBase::FileInfo & info)214 bool OhosResourceAdapterImpl::GetFileInfo(const std::shared_ptr<OHOS::AbilityBase::Extractor>& manager,
215 const std::string& rawFile, OHOS::AbilityBase::FileInfo& info)
216 {
217 if (!manager) {
218 return false;
219 }
220 return manager->GetFileInfo(rawFile, info);
221 }
222
GetModuleName(const char * configStr,size_t len)223 std::string OhosResourceAdapterImpl::GetModuleName(const char *configStr, size_t len)
224 {
225 if (configStr == nullptr) {
226 return std::string();
227 }
228 std::string config(configStr, len);
229 static const char *key = "\"moduleName\"";
230 auto idx = config.find(key);
231 if (idx == std::string::npos) {
232 return std::string();
233 }
234 auto start = config.find("\"", idx + strlen(key));
235 if (start == std::string::npos) {
236 return std::string();
237 }
238 auto end = config.find("\"", start + 1);
239 if (end == std::string::npos) {
240 return std::string();
241 }
242
243 std::string retStr = std::string(configStr + start + 1, end - start - 1);
244 return retStr;
245 }
246
ParseModuleName(const std::shared_ptr<Extractor> & manager)247 std::string OhosResourceAdapterImpl::ParseModuleName(const std::shared_ptr<Extractor> &manager)
248 {
249 if (manager == nullptr) {
250 return std::string();
251 }
252 std::unique_ptr<uint8_t[]> configBuf;
253 size_t len;
254 bool ret = manager->ExtractToBufByName("config.json", configBuf, len);
255 if (!ret) {
256 WVLOG_E("failed to get config data from ability");
257 return std::string();
258 }
259 // parse config.json
260 std::string mName = GetModuleName(reinterpret_cast<char *>(configBuf.get()), len);
261 if (mName.size() == 0) {
262 WVLOG_E("parse moduleName from config.json error");
263 return std::string();
264 }
265 return mName;
266 }
267
GetRawFileData(const std::shared_ptr<Extractor> & manager,const std::string & rawFile,size_t & len,std::unique_ptr<uint8_t[]> & dest)268 bool OhosResourceAdapterImpl::GetRawFileData(const std::shared_ptr<Extractor>& manager,
269 const std::string& rawFile, size_t& len, std::unique_ptr<uint8_t[]>& dest)
270 {
271 if (!manager) {
272 return false;
273 }
274 if (manager->IsStageModel()) {
275 return manager->ExtractToBufByName(rawFile, dest, len);
276 }
277 std::string moduleName = OhosResourceAdapterImpl::ParseModuleName(manager);
278 std::string rawFilePath("assets/");
279 rawFilePath.append(moduleName);
280 rawFilePath.append("/");
281 rawFilePath.append(rawFile);
282 WVLOG_E("fa filepath:%{public}s", rawFilePath.c_str());
283 return manager->ExtractToBufByName(rawFilePath, dest, len);
284 }
285
GetRawFileMapper(const std::shared_ptr<OHOS::AbilityBase::Extractor> & manager,const std::string & rawFile,std::unique_ptr<OhosFileMapper> & dest)286 bool OhosResourceAdapterImpl::GetRawFileMapper(const std::shared_ptr<OHOS::AbilityBase::Extractor>& manager,
287 const std::string& rawFile, std::unique_ptr<OhosFileMapper>& dest)
288 {
289 if (!manager) {
290 return false;
291 }
292 std::unique_ptr<OHOS::AbilityBase::FileMapper> fileMap = manager->GetMmapData(rawFile);
293 if (fileMap == nullptr) {
294 return false;
295 }
296 bool isCompressed = fileMap->IsCompressed();
297 dest = std::make_unique<OhosFileMapperImpl>(std::move(fileMap), isCompressed ? manager: nullptr);
298 return true;
299 }
300 } // namespace OHOS::NWeb
301