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 #include "js_module_reader.h"
17
18 #include "bundle_info.h"
19 #include "bundle_mgr_helper.h"
20 #include "bundle_mgr_proxy.h"
21 #include "file_path_utils.h"
22 #include "hilog_tag_wrapper.h"
23 #include "hitrace_meter.h"
24 #include "iservice_registry.h"
25 #include "js_runtime_utils.h"
26 #include "singleton.h"
27 #include "system_ability_definition.h"
28
29 using namespace OHOS::AbilityBase;
30
31 namespace OHOS {
32 namespace AbilityRuntime {
33 using IBundleMgr = AppExecFwk::IBundleMgr;
34
JsModuleReader(const std::string & bundleName,const std::string & hapPath,bool isFormRender)35 JsModuleReader::JsModuleReader(const std::string& bundleName, const std::string& hapPath, bool isFormRender)
36 : JsModuleSearcher(bundleName), isFormRender_(isFormRender)
37 {
38 if (!hapPath.empty() && hapPath.find(std::string(ABS_DATA_CODE_PATH)) != 0) {
39 isSystemPath_ = true;
40 } else {
41 isSystemPath_ = false;
42 }
43 }
44
operator ()(const std::string & inputPath,uint8_t ** buff,size_t * buffSize,std::string & errorMsg) const45 bool JsModuleReader::operator()(const std::string& inputPath, uint8_t **buff,
46 size_t *buffSize, std::string& errorMsg) const
47 {
48 TAG_LOGD(AAFwkTag::JSRUNTIME, "called start: %{private}s", inputPath.c_str());
49 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
50 if (inputPath.empty() || buff == nullptr || buffSize == nullptr) {
51 TAG_LOGE(AAFwkTag::JSRUNTIME, "Invalid param");
52 return false;
53 }
54
55 auto realHapPath = GetAppHspPath(inputPath);
56 if (realHapPath.empty()) {
57 TAG_LOGE(AAFwkTag::JSRUNTIME, "empty realHapPath");
58 return false;
59 }
60
61 bool newCreate = false;
62 std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor(realHapPath, newCreate);
63 if (extractor == nullptr) {
64 errorMsg = "hap path error: " + realHapPath;
65 TAG_LOGE(AAFwkTag::JSRUNTIME, "realHapPath %{private}s GetExtractor failed", realHapPath.c_str());
66 return false;
67 }
68
69 auto data = extractor->GetSafeData(MERGE_ABC_PATH);
70 if (!data) {
71 TAG_LOGE(AAFwkTag::JSRUNTIME, "null data");
72 return false;
73 }
74
75 *buff = data->GetDataPtr();
76 *buffSize = data->GetDataLen();
77 return true;
78 }
79
GetAppHspPath(const std::string & inputPath) const80 std::string JsModuleReader::GetAppHspPath(const std::string& inputPath) const
81 {
82 if (isFormRender_) {
83 return GetFormAppHspPath(inputPath);
84 }
85 return GetCommonAppHspPath(inputPath);
86 }
87
GetFormAppHspPath(const std::string & inputPath) const88 std::string JsModuleReader::GetFormAppHspPath(const std::string& inputPath) const
89 {
90 std::string realHapPath;
91 std::string suffix = std::string(SHARED_FILE_SUFFIX);
92 realHapPath.append("/data/bundles/")
93 .append(bundleName_).append("/")
94 .append(GetModuleName(inputPath))
95 .append(SHARED_FILE_SUFFIX);
96
97 TAG_LOGI(AAFwkTag::JSRUNTIME, "realHapPath: %{private}s", realHapPath.c_str());
98 if (realHapPath.empty() ||
99 realHapPath.length() < suffix.length() ||
100 realHapPath.compare(realHapPath.length() - suffix.length(), suffix.length(), suffix) != 0) {
101 TAG_LOGE(AAFwkTag::JSRUNTIME, "failed to obtain realHapPath");
102 return realHapPath;
103 }
104 return realHapPath;
105 }
106
GetModuleName(const std::string & inputPath) const107 std::string JsModuleReader::GetModuleName(const std::string& inputPath) const
108 {
109 return inputPath.substr(inputPath.find_last_of("/") + 1);
110 }
111
GetCommonAppHspPath(const std::string & inputPath) const112 std::string JsModuleReader::GetCommonAppHspPath(const std::string& inputPath) const
113 {
114 std::string suffix = std::string(SHARED_FILE_SUFFIX);
115 std::string realHapPath = GetPresetAppHapPath(inputPath, bundleName_);
116 if ((realHapPath.find(ABS_DATA_CODE_PATH) == 0) || (realHapPath == inputPath)) {
117 realHapPath = std::string(ABS_CODE_PATH) + inputPath + suffix;
118 }
119
120 TAG_LOGD(AAFwkTag::JSRUNTIME, "realHapPath: %{private}s", realHapPath.c_str());
121 if (realHapPath.empty() ||
122 realHapPath.length() < suffix.length() ||
123 realHapPath.compare(realHapPath.length() - suffix.length(), suffix.length(), suffix) != 0) {
124 TAG_LOGE(AAFwkTag::JSRUNTIME, "failed to obtain realHapPath");
125 return realHapPath;
126 }
127 return realHapPath;
128 }
129
GetOtherHspPath(const std::string & bundleName,const std::string & moduleName,const std::string & inputPath)130 std::string JsModuleReader::GetOtherHspPath(const std::string& bundleName, const std::string& moduleName,
131 const std::string& inputPath)
132 {
133 std::string presetAppHapPath = inputPath;
134
135 auto bundleMgrHelper = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
136 if (bundleMgrHelper == nullptr) {
137 TAG_LOGE(AAFwkTag::JSRUNTIME, "null bundleMgrHelper");
138 return presetAppHapPath;
139 }
140
141 std::vector<AppExecFwk::BaseSharedBundleInfo> baseSharedBundleInfos;
142 if (bundleMgrHelper->GetBaseSharedBundleInfos(bundleName, baseSharedBundleInfos) != 0) {
143 TAG_LOGE(AAFwkTag::JSRUNTIME, "GetBaseSharedBundleInfos failed");
144 return presetAppHapPath;
145 }
146 std::string tmpPath = inputPath.substr(inputPath.find_first_of("/") + 1);
147 const std::string sharedBundleName = tmpPath.substr(0, tmpPath.find_first_of("/"));
148 for (const auto &info : baseSharedBundleInfos) {
149 if ((info.bundleName == sharedBundleName) && (info.moduleName == moduleName)) {
150 presetAppHapPath = info.hapPath;
151 break;
152 }
153 }
154 AppExecFwk::BundleInfo bundleInfo;
155 int32_t ret = bundleMgrHelper->GetDependentBundleInfo(sharedBundleName, bundleInfo,
156 AppExecFwk::GetDependentBundleInfoFlag::GET_APP_SERVICE_HSP_BUNDLE_INFO);
157 if (ret != ERR_OK) {
158 TAG_LOGE(AAFwkTag::JSRUNTIME, "GetDependentBundleInfo failed");
159 return presetAppHapPath;
160 }
161 for (const auto &info : bundleInfo.hapModuleInfos) {
162 if (info.moduleName == moduleName) {
163 presetAppHapPath = info.hapPath;
164 break;
165 }
166 }
167 return presetAppHapPath;
168 }
169
GetPresetAppHapPath(const std::string & inputPath,const std::string & bundleName)170 std::string JsModuleReader::GetPresetAppHapPath(const std::string& inputPath, const std::string& bundleName)
171 {
172 std::string presetAppHapPath = inputPath;
173 std::string moduleName = inputPath.substr(inputPath.find_last_of("/") + 1);
174 if (moduleName.empty()) {
175 TAG_LOGE(AAFwkTag::JSRUNTIME, "empty moduleName");
176 return presetAppHapPath;
177 }
178 auto bundleMgrHelper = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
179 if (bundleMgrHelper == nullptr) {
180 TAG_LOGE(AAFwkTag::JSRUNTIME, "null bundleMgrHelper");
181 return presetAppHapPath;
182 }
183 if (inputPath.find_first_of("/") == inputPath.find_last_of("/")) {
184 AppExecFwk::BundleInfo bundleInfo;
185 auto getInfoResult = bundleMgrHelper->GetBundleInfoForSelf(static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::
186 GET_BUNDLE_INFO_WITH_HAP_MODULE), bundleInfo);
187 if (getInfoResult != 0 || bundleInfo.hapModuleInfos.empty()) {
188 TAG_LOGE(AAFwkTag::JSRUNTIME, "GetBundleInfoForSelf failed");
189 return presetAppHapPath;
190 }
191 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
192 if (hapModuleInfo.moduleName == moduleName) {
193 presetAppHapPath = hapModuleInfo.hapPath;
194 break;
195 }
196 }
197 } else {
198 presetAppHapPath = GetOtherHspPath(bundleName, moduleName, presetAppHapPath);
199 }
200 return presetAppHapPath;
201 }
202
GetHapPathList(const std::string & bundleName,std::vector<std::string> & hapList)203 void JsModuleReader::GetHapPathList(const std::string &bundleName, std::vector<std::string> &hapList)
204 {
205 auto systemAbilityManagerClient = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
206 if (!systemAbilityManagerClient) {
207 TAG_LOGE(AAFwkTag::JSRUNTIME, "null systemAbilityManagerClient");
208 return;
209 }
210 auto remoteObject = systemAbilityManagerClient->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
211 if (!remoteObject) {
212 TAG_LOGE(AAFwkTag::JSRUNTIME, "null remoteObject");
213 return;
214 }
215 auto bundleMgrProxy = iface_cast<IBundleMgr>(remoteObject);
216 AppExecFwk::BundleInfo bundleInfo;
217 auto getInfoResult = bundleMgrProxy->GetBundleInfoForSelf(static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::
218 GET_BUNDLE_INFO_WITH_HAP_MODULE), bundleInfo);
219 if (getInfoResult != 0 || bundleInfo.hapModuleInfos.empty()) {
220 TAG_LOGE(AAFwkTag::JSRUNTIME, "GetBundleInfoForSelf failed");
221 return;
222 }
223 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
224 hapList.emplace_back(hapModuleInfo.hapPath);
225 }
226 }
227 } // namespace AbilityRuntime
228 } // namespace OHOS