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 "native_interface_bundle.h"
17 
18 #include <mutex>
19 #include <string>
20 
21 #include "application_info.h"
22 #include "bundle_info.h"
23 #include "app_log_wrapper.h"
24 #include "bundle_mgr_proxy_native.h"
25 #include "ipc_skeleton.h"
26 #include "securec.h"
27 namespace {
28 const size_t CHAR_MAX_LENGTH = 10240;
29 }
30 
31 // Helper function to release char* memory
ReleaseMemory(char * & str)32 static void ReleaseMemory(char* &str)
33 {
34     if (str != nullptr) {
35         free(str);
36         str = nullptr;
37     }
38 }
39 
40 template <typename... Args>
ReleaseStrings(Args...args)41 void ReleaseStrings(Args... args)
42 {
43     (ReleaseMemory(args), ...);
44 }
45 
CopyStringToChar(char * & name,const std::string & value)46 bool CopyStringToChar(char* &name, const std::string &value)
47 {
48     size_t length = value.size();
49     if ((length == 0) || (length + 1) > CHAR_MAX_LENGTH) {
50         APP_LOGE("failed due to the length of value is empty or too long");
51         return false;
52     }
53     name = static_cast<char*>(malloc(length + 1));
54     if (name == nullptr) {
55         APP_LOGE("failed due to malloc error");
56         return false;
57     }
58     if (strcpy_s(name, length + 1, value.c_str()) != EOK) {
59         APP_LOGE("failed due to strcpy_s error");
60         ReleaseStrings(name);
61         return false;
62     }
63     return true;
64 }
65 
GetElementNameByAbilityInfo(const OHOS::AppExecFwk::AbilityInfo & abilityInfo,OH_NativeBundle_ElementName & elementName)66 bool GetElementNameByAbilityInfo(
67     const OHOS::AppExecFwk::AbilityInfo &abilityInfo, OH_NativeBundle_ElementName &elementName)
68 {
69     if (!CopyStringToChar(elementName.bundleName, abilityInfo.bundleName)) {
70         APP_LOGE("failed to obtains bundleName");
71         return false;
72     }
73 
74     if (!CopyStringToChar(elementName.moduleName, abilityInfo.moduleName)) {
75         APP_LOGE("failed to obtains moduleName");
76         ReleaseStrings(elementName.bundleName);
77         return false;
78     }
79 
80     if (!CopyStringToChar(elementName.abilityName, abilityInfo.name)) {
81         APP_LOGE("failed to obtains abilityName");
82         ReleaseStrings(elementName.bundleName, elementName.moduleName);
83         return false;
84     }
85     return true;
86 }
87 
GetElementNameByModuleInfo(const OHOS::AppExecFwk::HapModuleInfo & hapModuleInfo,OH_NativeBundle_ElementName & elementName)88 bool GetElementNameByModuleInfo(
89     const OHOS::AppExecFwk::HapModuleInfo &hapModuleInfo, OH_NativeBundle_ElementName &elementName)
90 {
91     for (const auto &abilityInfo : hapModuleInfo.abilityInfos) {
92         if (abilityInfo.name.compare(hapModuleInfo.mainElementName) == 0) {
93             return GetElementNameByAbilityInfo(abilityInfo, elementName);
94         }
95     }
96     return false;
97 }
98 
OH_NativeBundle_GetCurrentApplicationInfo()99 OH_NativeBundle_ApplicationInfo OH_NativeBundle_GetCurrentApplicationInfo()
100 {
101     OH_NativeBundle_ApplicationInfo nativeApplicationInfo;
102     OHOS::AppExecFwk::BundleMgrProxyNative bundleMgrProxyNative;
103     OHOS::AppExecFwk::BundleInfo bundleInfo;
104     auto bundleInfoFlag = static_cast<int32_t>(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
105         static_cast<int32_t>(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO);
106 
107     if (!bundleMgrProxyNative.GetBundleInfoForSelf(bundleInfoFlag, bundleInfo)) {
108         APP_LOGE("can not get bundleInfo for self");
109         return nativeApplicationInfo;
110     };
111     size_t bundleNameLen = bundleInfo.applicationInfo.bundleName.size();
112     if ((bundleNameLen == 0) || (bundleNameLen + 1) > CHAR_MAX_LENGTH) {
113         APP_LOGE("failed due to the length of bundleName is empty or too long");
114         return nativeApplicationInfo;
115     }
116     nativeApplicationInfo.bundleName = static_cast<char*>(malloc(bundleNameLen + 1));
117     if (nativeApplicationInfo.bundleName == nullptr) {
118         APP_LOGE("failed due to malloc error");
119         return nativeApplicationInfo;
120     }
121     if (strcpy_s(nativeApplicationInfo.bundleName, bundleNameLen + 1,
122         bundleInfo.applicationInfo.bundleName.c_str()) != EOK) {
123         APP_LOGE("failed due to strcpy_s error");
124         ReleaseStrings(nativeApplicationInfo.bundleName);
125         return nativeApplicationInfo;
126     }
127     size_t fingerprintLen = bundleInfo.signatureInfo.fingerprint.size();
128     if ((fingerprintLen == 0) || (fingerprintLen + 1) > CHAR_MAX_LENGTH) {
129         APP_LOGE("failed due to the length of fingerprint is empty or too long");
130         ReleaseStrings(nativeApplicationInfo.bundleName);
131         return nativeApplicationInfo;
132     }
133     nativeApplicationInfo.fingerprint = static_cast<char*>(malloc(fingerprintLen + 1));
134     if (nativeApplicationInfo.fingerprint == nullptr) {
135         APP_LOGE("failed due to malloc error");
136         ReleaseStrings(nativeApplicationInfo.bundleName);
137         return nativeApplicationInfo;
138     }
139     if (strcpy_s(nativeApplicationInfo.fingerprint, fingerprintLen + 1,
140         bundleInfo.signatureInfo.fingerprint.c_str()) != EOK) {
141         APP_LOGE("failed due to strcpy_s error");
142         ReleaseStrings(nativeApplicationInfo.bundleName, nativeApplicationInfo.fingerprint);
143         return nativeApplicationInfo;
144     }
145     APP_LOGI("OH_NativeBundle_GetCurrentApplicationInfo success");
146     return nativeApplicationInfo;
147 }
148 
OH_NativeBundle_GetAppId()149 char* OH_NativeBundle_GetAppId()
150 {
151     OHOS::AppExecFwk::BundleMgrProxyNative bundleMgrProxyNative;
152     OHOS::AppExecFwk::BundleInfo bundleInfo;
153     auto bundleInfoFlag =
154         static_cast<int32_t>(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO);
155 
156     if (!bundleMgrProxyNative.GetBundleInfoForSelf(bundleInfoFlag, bundleInfo)) {
157         APP_LOGE("can not get bundleInfo for self");
158         return nullptr;
159     };
160 
161     size_t appIdLen = bundleInfo.signatureInfo.appId.size();
162     if ((appIdLen == 0) || (appIdLen + 1) > CHAR_MAX_LENGTH) {
163         APP_LOGE("failed due to the length of appId is empty or too long");
164         return nullptr;
165     }
166     char *appId = static_cast<char*>(malloc(appIdLen + 1));
167     if (appId == nullptr) {
168         APP_LOGE("failed due to malloc error");
169         return nullptr;
170     }
171     if (strcpy_s(appId, appIdLen + 1, bundleInfo.signatureInfo.appId.c_str()) != EOK) {
172         APP_LOGE("failed due to strcpy_s error");
173         free(appId);
174         return nullptr;
175     }
176     APP_LOGI("OH_NativeBundle_GetAppId success");
177     return appId;
178 }
179 
OH_NativeBundle_GetAppIdentifier()180 char* OH_NativeBundle_GetAppIdentifier()
181 {
182     OHOS::AppExecFwk::BundleMgrProxyNative bundleMgrProxyNative;
183     OHOS::AppExecFwk::BundleInfo bundleInfo;
184     auto bundleInfoFlag =
185         static_cast<int32_t>(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO);
186 
187     if (!bundleMgrProxyNative.GetBundleInfoForSelf(bundleInfoFlag, bundleInfo)) {
188         APP_LOGE("can not get bundleInfo for self");
189         return nullptr;
190     };
191 
192     size_t appIdentifierLen = bundleInfo.signatureInfo.appIdentifier.size();
193     if (appIdentifierLen + 1 > CHAR_MAX_LENGTH) {
194         APP_LOGE("failed due to the length of appIdentifier is too long");
195         return nullptr;
196     }
197     char* appIdentifier = static_cast<char*>(malloc(appIdentifierLen + 1));
198     if (appIdentifier == nullptr) {
199         APP_LOGE("failed due to malloc error");
200         return nullptr;
201     }
202     if (strcpy_s(appIdentifier, appIdentifierLen + 1,
203         bundleInfo.signatureInfo.appIdentifier.c_str()) != EOK) {
204         APP_LOGE("failed due to strcpy_s error");
205         free(appIdentifier);
206         return nullptr;
207     }
208     APP_LOGI("OH_NativeBundle_GetAppIdentifier success");
209     return appIdentifier;
210 }
211 
OH_NativeBundle_GetMainElementName()212 OH_NativeBundle_ElementName OH_NativeBundle_GetMainElementName()
213 {
214     OH_NativeBundle_ElementName elementName;
215     OHOS::AppExecFwk::BundleMgrProxyNative bundleMgrProxyNative;
216     OHOS::AppExecFwk::BundleInfo bundleInfo;
217     auto bundleInfoFlag = static_cast<int32_t>(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
218                           static_cast<int32_t>(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY);
219 
220     if (!bundleMgrProxyNative.GetBundleInfoForSelf(bundleInfoFlag, bundleInfo)) {
221         APP_LOGE("can not get bundleInfo for self");
222         return elementName;
223     };
224 
225     for (const auto &hapModuleInfo : bundleInfo.hapModuleInfos) {
226         if (hapModuleInfo.moduleType != OHOS::AppExecFwk::ModuleType::ENTRY) {
227             continue;
228         }
229         if (GetElementNameByModuleInfo(hapModuleInfo, elementName)) {
230             return elementName;
231         }
232     }
233 
234     for (const auto &hapModuleInfo : bundleInfo.hapModuleInfos) {
235         if (hapModuleInfo.moduleType != OHOS::AppExecFwk::ModuleType::FEATURE) {
236             continue;
237         }
238         if (GetElementNameByModuleInfo(hapModuleInfo, elementName)) {
239             return elementName;
240         }
241     }
242 
243     for (const auto &hapModuleInfo : bundleInfo.hapModuleInfos) {
244         for (const auto &abilityInfo : hapModuleInfo.abilityInfos) {
245             GetElementNameByAbilityInfo(abilityInfo, elementName);
246             return elementName;
247         }
248     }
249     return elementName;
250 }
251 
OH_NativeBundle_GetCompatibleDeviceType()252 char* OH_NativeBundle_GetCompatibleDeviceType()
253 {
254     OHOS::AppExecFwk::BundleMgrProxyNative bundleMgrProxyNative;
255     std::string deviceType;
256     if (!bundleMgrProxyNative.GetCompatibleDeviceTypeNative(deviceType)) {
257         APP_LOGE("can not get compatible device type");
258         return nullptr;
259     }
260     if (deviceType.size() + 1 > CHAR_MAX_LENGTH) {
261         APP_LOGE("failed due to the length of device type is too long");
262         return nullptr;
263     }
264     char* deviceTypeC = static_cast<char*>(malloc(deviceType.size() + 1));
265     if (deviceTypeC == nullptr) {
266         APP_LOGE("failed due to malloc error");
267         return nullptr;
268     }
269     if (strcpy_s(deviceTypeC, deviceType.size() + 1, deviceType.c_str()) != EOK) {
270         APP_LOGE("failed due to strcpy_s error");
271         free(deviceTypeC);
272         return nullptr;
273     }
274     APP_LOGI("OH_NativeBundle_GetCompatibleDeviceType success");
275     return deviceTypeC;
276 }
277