1 /*
2 * Copyright (c) 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 "ets_native_lib_util.h"
17
18 #include "constants.h"
19 #include "hilog_tag_wrapper.h"
20
21 namespace OHOS {
22 namespace AppExecFwk {
23 constexpr char APP_ABC_LIB_PATH_KEY_PREFIX[] = "/data/storage/el1/bundle/";
24 constexpr char APP_ABC_LIB_PATH_KEY_SUFFIX[] = "/ets/modules_static.abc";
25
GetEtsLibPath(const std::string & hapPath,bool isPreInstallApp)26 std::string GetEtsLibPath(const std::string &hapPath, bool isPreInstallApp)
27 {
28 std::string libPath = AbilityBase::Constants::LOCAL_CODE_PATH;
29 if (isPreInstallApp) {
30 auto pos = hapPath.rfind("/");
31 libPath = hapPath.substr(0, pos);
32 }
33 return libPath;
34 }
35
GetEtsHapSoPath(const HapModuleInfo & hapInfo,AppLibPathMap & appLibPaths,bool isPreInstallApp,std::map<std::string,std::string> & abcPathsToBundleModuleNameMap)36 void GetEtsHapSoPath(const HapModuleInfo &hapInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp,
37 std::map<std::string, std::string> &abcPathsToBundleModuleNameMap)
38 {
39 if (hapInfo.nativeLibraryPath.empty()) {
40 TAG_LOGD(AAFwkTag::APPKIT, "Lib path of %{public}s is empty, lib isn't isolated or compressed",
41 hapInfo.moduleName.c_str());
42 return;
43 }
44
45 std::string appLibPathKey = hapInfo.bundleName + "/" + hapInfo.moduleName;
46 std::string libPath = AbilityBase::Constants::LOCAL_CODE_PATH;
47 if (!hapInfo.compressNativeLibs) {
48 TAG_LOGD(AAFwkTag::APPKIT, "Lib of %{public}s will not be extracted from hap", hapInfo.moduleName.c_str());
49 libPath = GetEtsLibPath(hapInfo.hapPath, isPreInstallApp);
50 }
51
52 libPath += (libPath.back() == '/') ? hapInfo.nativeLibraryPath : "/" + hapInfo.nativeLibraryPath;
53 TAG_LOGD(
54 AAFwkTag::APPKIT, "appLibPathKey: %{private}s, lib path: %{private}s", appLibPathKey.c_str(), libPath.c_str());
55 appLibPaths[appLibPathKey].emplace_back(libPath);
56
57 std::string appLibAbcPathKey = APP_ABC_LIB_PATH_KEY_PREFIX + hapInfo.moduleName + APP_ABC_LIB_PATH_KEY_SUFFIX;
58 abcPathsToBundleModuleNameMap[appLibAbcPathKey] = appLibPathKey;
59 }
60
GetEtsHspNativeLibPath(const BaseSharedBundleInfo & hspInfo,AppLibPathMap & appLibPaths,bool isPreInstallApp,const std::string & appBundleName,std::map<std::string,std::string> & abcPathsToBundleModuleNameMap)61 void GetEtsHspNativeLibPath(const BaseSharedBundleInfo &hspInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp,
62 const std::string &appBundleName, std::map<std::string, std::string> &abcPathsToBundleModuleNameMap)
63 {
64 if (hspInfo.nativeLibraryPath.empty()) {
65 return;
66 }
67
68 std::string appLibPathKey = hspInfo.bundleName + "/" + hspInfo.moduleName;
69 std::string libPath = AbilityBase::Constants::LOCAL_CODE_PATH;
70 if (!hspInfo.compressNativeLibs) {
71 libPath = GetEtsLibPath(hspInfo.hapPath, isPreInstallApp);
72 libPath = libPath.back() == '/' ? libPath : libPath + "/";
73 if (isPreInstallApp) {
74 libPath += hspInfo.nativeLibraryPath;
75 } else {
76 libPath += hspInfo.bundleName + "/" + hspInfo.moduleName + "/" + hspInfo.nativeLibraryPath;
77 }
78 } else {
79 libPath = libPath.back() == '/' ? libPath : libPath + "/";
80 libPath += hspInfo.bundleName + "/" + hspInfo.nativeLibraryPath;
81 }
82
83 TAG_LOGD(
84 AAFwkTag::APPKIT, "appLibPathKey: %{private}s, libPath: %{private}s", appLibPathKey.c_str(), libPath.c_str());
85 appLibPaths[appLibPathKey].emplace_back(libPath);
86
87 if (!appBundleName.empty()) {
88 const bool isInternalHsp = (hspInfo.bundleName == appBundleName);
89 const std::string name = isInternalHsp ? hspInfo.moduleName : hspInfo.bundleName + "/" + hspInfo.moduleName;
90 const std::string appLibAbcPathKey = APP_ABC_LIB_PATH_KEY_PREFIX + name + APP_ABC_LIB_PATH_KEY_SUFFIX;
91 abcPathsToBundleModuleNameMap[appLibAbcPathKey] = appLibPathKey;
92 }
93 }
94
GetEtsPatchNativeLibPath(const HapModuleInfo & hapInfo,std::string & patchNativeLibraryPath,AppLibPathMap & appLibPaths,std::map<std::string,std::string> & abcPathsToBundleModuleNameMap)95 void GetEtsPatchNativeLibPath(const HapModuleInfo &hapInfo, std::string &patchNativeLibraryPath,
96 AppLibPathMap &appLibPaths, std::map<std::string, std::string> &abcPathsToBundleModuleNameMap)
97 {
98 if (hapInfo.isLibIsolated) {
99 patchNativeLibraryPath = hapInfo.hqfInfo.nativeLibraryPath;
100 }
101
102 if (patchNativeLibraryPath.empty()) {
103 TAG_LOGD(AAFwkTag::APPKIT, "Patch lib path of %{public}s is empty", hapInfo.moduleName.c_str());
104 return;
105 }
106
107 if (hapInfo.compressNativeLibs && !hapInfo.isLibIsolated) {
108 TAG_LOGD(AAFwkTag::APPKIT, "Lib of %{public}s has compressed and isn't isolated, no need to set",
109 hapInfo.moduleName.c_str());
110 return;
111 }
112
113 std::string appLibPathKey = hapInfo.bundleName + "/" + hapInfo.moduleName;
114 std::string patchLibPath = AbilityBase::Constants::LOCAL_CODE_PATH;
115 patchLibPath += (patchLibPath.back() == '/') ? patchNativeLibraryPath : "/" + patchNativeLibraryPath;
116 TAG_LOGD(AAFwkTag::APPKIT, "appLibPathKey: %{public}s, patch lib path: %{private}s", appLibPathKey.c_str(),
117 patchLibPath.c_str());
118 appLibPaths[appLibPathKey].emplace_back(patchLibPath);
119 std::string appLibAbcPathKey = APP_ABC_LIB_PATH_KEY_PREFIX + hapInfo.moduleName + APP_ABC_LIB_PATH_KEY_SUFFIX;
120 abcPathsToBundleModuleNameMap[appLibAbcPathKey] = appLibPathKey;
121 }
122
GetEtsNativeLibPath(const BundleInfo & bundleInfo,const std::vector<BaseSharedBundleInfo> & hspList,AppLibPathMap & appLibPaths,std::map<std::string,std::string> & abcPathsToBundleModuleNameMap)123 void GetEtsNativeLibPath(const BundleInfo &bundleInfo, const std::vector<BaseSharedBundleInfo> &hspList,
124 AppLibPathMap &appLibPaths, std::map<std::string, std::string> &abcPathsToBundleModuleNameMap)
125 {
126 std::string patchNativeLibraryPath = bundleInfo.applicationInfo.appQuickFix.deployedAppqfInfo.nativeLibraryPath;
127 abcPathsToBundleModuleNameMap["default"] = "default";
128 if (!patchNativeLibraryPath.empty()) {
129 // libraries in patch lib path has a higher priority when loading.
130 std::string patchLibPath = AbilityBase::Constants::LOCAL_CODE_PATH;
131 patchLibPath += (patchLibPath.back() == '/') ? patchNativeLibraryPath : "/" + patchNativeLibraryPath;
132 TAG_LOGD(AAFwkTag::APPKIT, "lib path = %{private}s", patchLibPath.c_str());
133 appLibPaths["default"].emplace_back(patchLibPath);
134 }
135
136 std::string nativeLibraryPath = bundleInfo.applicationInfo.nativeLibraryPath;
137 if (!nativeLibraryPath.empty()) {
138 if (nativeLibraryPath.back() == '/') {
139 nativeLibraryPath.pop_back();
140 }
141 std::string libPath = AbilityBase::Constants::LOCAL_CODE_PATH;
142 libPath += (libPath.back() == '/') ? nativeLibraryPath : "/" + nativeLibraryPath;
143 TAG_LOGD(AAFwkTag::APPKIT, "lib path = %{private}s", libPath.c_str());
144 appLibPaths["default"].emplace_back(libPath);
145 } else {
146 TAG_LOGI(AAFwkTag::APPKIT, "nativeLibraryPath is empty");
147 }
148
149 for (auto &hapInfo : bundleInfo.hapModuleInfos) {
150 TAG_LOGD(AAFwkTag::APPKIT,
151 "moduleName: %{public}s, isLibIsolated: %{public}d, compressNativeLibs: %{public}d.",
152 hapInfo.moduleName.c_str(), hapInfo.isLibIsolated, hapInfo.compressNativeLibs);
153 GetEtsPatchNativeLibPath(hapInfo, patchNativeLibraryPath, appLibPaths, abcPathsToBundleModuleNameMap);
154 GetEtsHapSoPath(hapInfo, appLibPaths, hapInfo.hapPath.find(AbilityBase::Constants::ABS_CODE_PATH),
155 abcPathsToBundleModuleNameMap);
156 }
157
158 for (auto &hspInfo : hspList) {
159 TAG_LOGD(AAFwkTag::APPKIT, "bundle:%s, module:%s, nativeLibraryPath:%s", hspInfo.bundleName.c_str(),
160 hspInfo.moduleName.c_str(), hspInfo.nativeLibraryPath.c_str());
161 GetEtsHspNativeLibPath(hspInfo, appLibPaths, hspInfo.hapPath.find(AbilityBase::Constants::ABS_CODE_PATH) != 0u,
162 bundleInfo.applicationInfo.bundleName, abcPathsToBundleModuleNameMap);
163 }
164 }
165 } // AppExecFwk
166 } // namespace OHOS