1 /*
2 * Copyright (c) 2022-2023 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_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) const45 bool JsModuleReader::operator()(const std::string& inputPath, uint8_t **buff, size_t *buffSize) const
46 {
47 HILOG_DEBUG("JsModuleReader operator start: %{private}s", inputPath.c_str());
48 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
49 if (inputPath.empty() || buff == nullptr || buffSize == nullptr) {
50 HILOG_ERROR("Invalid param");
51 return false;
52 }
53
54 auto realHapPath = GetAppHspPath(inputPath);
55 if (realHapPath.empty()) {
56 HILOG_ERROR("realHapPath is empty");
57 return false;
58 }
59
60 bool newCreate = false;
61 std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor(realHapPath, newCreate);
62 if (extractor == nullptr) {
63 HILOG_ERROR("realHapPath %{private}s GetExtractor failed", realHapPath.c_str());
64 return false;
65 }
66
67 auto data = extractor->GetSafeData(MERGE_ABC_PATH);
68 if (!data) {
69 HILOG_ERROR("get mergeAbc fileBuffer failed");
70 return false;
71 }
72
73 *buff = data->GetDataPtr();
74 *buffSize = data->GetDataLen();
75 return true;
76 }
77
GetAppHspPath(const std::string & inputPath) const78 std::string JsModuleReader::GetAppHspPath(const std::string& inputPath) const
79 {
80 if (isFormRender_) {
81 return GetFormAppHspPath(inputPath);
82 }
83 return GetCommonAppHspPath(inputPath);
84 }
85
GetFormAppHspPath(const std::string & inputPath) const86 std::string JsModuleReader::GetFormAppHspPath(const std::string& inputPath) const
87 {
88 std::string realHapPath;
89 std::string suffix = std::string(SHARED_FILE_SUFFIX);
90 realHapPath.append("/data/bundles/")
91 .append(bundleName_).append("/")
92 .append(GetModuleName(inputPath))
93 .append(SHARED_FILE_SUFFIX);
94
95 HILOG_INFO("realHapPath: %{private}s", realHapPath.c_str());
96 if (realHapPath.empty() ||
97 realHapPath.length() < suffix.length() ||
98 realHapPath.compare(realHapPath.length() - suffix.length(), suffix.length(), suffix) != 0) {
99 HILOG_ERROR("failed to obtain realHapPath");
100 return realHapPath;
101 }
102 return realHapPath;
103 }
104
GetModuleName(const std::string & inputPath) const105 std::string JsModuleReader::GetModuleName(const std::string& inputPath) const
106 {
107 return inputPath.substr(inputPath.find_last_of("/") + 1);
108 }
109
GetCommonAppHspPath(const std::string & inputPath) const110 std::string JsModuleReader::GetCommonAppHspPath(const std::string& inputPath) const
111 {
112 std::string suffix = std::string(SHARED_FILE_SUFFIX);
113 std::string realHapPath = GetPresetAppHapPath(inputPath, bundleName_);
114 if ((realHapPath.find(ABS_DATA_CODE_PATH) == 0) || (realHapPath == inputPath)) {
115 realHapPath = std::string(ABS_CODE_PATH) + inputPath + suffix;
116 }
117
118 HILOG_DEBUG("realHapPath: %{private}s", realHapPath.c_str());
119 if (realHapPath.empty() ||
120 realHapPath.length() < suffix.length() ||
121 realHapPath.compare(realHapPath.length() - suffix.length(), suffix.length(), suffix) != 0) {
122 HILOG_ERROR("failed to obtain realHapPath");
123 return realHapPath;
124 }
125 return realHapPath;
126 }
127
GetOtherHspPath(const std::string & bundleName,const std::string & moduleName,const std::string & inputPath)128 std::string JsModuleReader::GetOtherHspPath(const std::string& bundleName, const std::string& moduleName,
129 const std::string& inputPath)
130 {
131 std::string presetAppHapPath = inputPath;
132
133 auto bundleMgrHelper = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
134 if (bundleMgrHelper == nullptr) {
135 HILOG_ERROR("The bundleMgrHelper is nullptr.");
136 return presetAppHapPath;
137 }
138
139 std::vector<AppExecFwk::BaseSharedBundleInfo> baseSharedBundleInfos;
140 if (bundleMgrHelper->GetBaseSharedBundleInfos(bundleName, baseSharedBundleInfos) != 0) {
141 HILOG_ERROR("GetBaseSharedBundleInfos failed.");
142 return presetAppHapPath;
143 }
144 std::string tmpPath = inputPath.substr(inputPath.find_first_of("/") + 1);
145 const std::string sharedBundleName = tmpPath.substr(0, tmpPath.find_first_of("/"));
146 for (const auto &info : baseSharedBundleInfos) {
147 if ((info.bundleName == sharedBundleName) && (info.moduleName == moduleName)) {
148 presetAppHapPath = info.hapPath;
149 break;
150 }
151 }
152 AppExecFwk::BundleInfo bundleInfo;
153 int32_t ret = bundleMgrHelper->GetDependentBundleInfo(sharedBundleName, bundleInfo,
154 AppExecFwk::GetDependentBundleInfoFlag::GET_APP_SERVICE_HSP_BUNDLE_INFO);
155 if (ret != ERR_OK) {
156 HILOG_ERROR("GetDependentBundleInfo failed.");
157 return presetAppHapPath;
158 }
159 for (const auto &info : bundleInfo.hapModuleInfos) {
160 if (info.moduleName == moduleName) {
161 presetAppHapPath = info.hapPath;
162 break;
163 }
164 }
165 return presetAppHapPath;
166 }
167
GetPresetAppHapPath(const std::string & inputPath,const std::string & bundleName)168 std::string JsModuleReader::GetPresetAppHapPath(const std::string& inputPath, const std::string& bundleName)
169 {
170 std::string presetAppHapPath = inputPath;
171 std::string moduleName = inputPath.substr(inputPath.find_last_of("/") + 1);
172 if (moduleName.empty()) {
173 HILOG_ERROR("Failed to obtain moduleName.");
174 return presetAppHapPath;
175 }
176 auto bundleMgrHelper = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
177 if (bundleMgrHelper == nullptr) {
178 HILOG_ERROR("The bundleMgrHelper is nullptr.");
179 return presetAppHapPath;
180 }
181 if (inputPath.find_first_of("/") == inputPath.find_last_of("/")) {
182 AppExecFwk::BundleInfo bundleInfo;
183 auto getInfoResult = bundleMgrHelper->GetBundleInfoForSelf(static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::
184 GET_BUNDLE_INFO_WITH_HAP_MODULE), bundleInfo);
185 if (getInfoResult != 0 || bundleInfo.hapModuleInfos.empty()) {
186 HILOG_ERROR("GetBundleInfoForSelf failed.");
187 return presetAppHapPath;
188 }
189 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
190 if (hapModuleInfo.moduleName == moduleName) {
191 presetAppHapPath = hapModuleInfo.hapPath;
192 break;
193 }
194 }
195 } else {
196 presetAppHapPath = GetOtherHspPath(bundleName, moduleName, presetAppHapPath);
197 }
198 return presetAppHapPath;
199 }
200
GetHapPathList(const std::string & bundleName,std::vector<std::string> & hapList)201 void JsModuleReader::GetHapPathList(const std::string &bundleName, std::vector<std::string> &hapList)
202 {
203 auto systemAbilityManagerClient = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
204 if (!systemAbilityManagerClient) {
205 HILOG_ERROR("fail to get system ability mgr.");
206 return;
207 }
208 auto remoteObject = systemAbilityManagerClient->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
209 if (!remoteObject) {
210 HILOG_ERROR("fail to get bundle manager proxy.");
211 return;
212 }
213 auto bundleMgrProxy = iface_cast<IBundleMgr>(remoteObject);
214 AppExecFwk::BundleInfo bundleInfo;
215 auto getInfoResult = bundleMgrProxy->GetBundleInfoForSelf(static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::
216 GET_BUNDLE_INFO_WITH_HAP_MODULE), bundleInfo);
217 if (getInfoResult != 0 || bundleInfo.hapModuleInfos.empty()) {
218 HILOG_ERROR("GetBundleInfoForSelf failed.");
219 return;
220 }
221 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
222 hapList.emplace_back(hapModuleInfo.hapPath);
223 }
224 }
225 } // namespace AbilityRuntime
226 } // namespace OHOS