1 /*
2 * Copyright (c) 2025 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 <ani_signature_builder.h>
17
18 #include "app_log_wrapper.h"
19 #include "bundle_errors.h"
20 #include "bundle_mgr_interface.h"
21 #include "bundle_mgr_proxy.h"
22 #include "business_error.h"
23 #include "business_error_ani.h"
24 #include "common_fun_ani.h"
25 #include "common_func.h"
26 #include "enum_util.h"
27 #include "napi_constants.h"
28
29 namespace OHOS {
30 namespace AppExecFwk {
31 namespace {
32 constexpr const char* NS_NAME_FREEINSTALL = "@ohos.bundle.freeInstall.freeInstall";
33 } // namespace
34
AniSetHapModuleUpgradeFlag(ani_env * env,ani_string aniBundleName,ani_string aniModuleName,ani_enum_item aniUpgradeFlag)35 static void AniSetHapModuleUpgradeFlag(
36 ani_env* env, ani_string aniBundleName, ani_string aniModuleName, ani_enum_item aniUpgradeFlag)
37 {
38 APP_LOGD("ani SetHapModuleUpgradeFlag called");
39 std::string bundleName;
40 if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
41 APP_LOGE("parse bundleName failed");
42 BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
43 return;
44 }
45
46 std::string moduleName;
47 if (!CommonFunAni::ParseString(env, aniModuleName, moduleName)) {
48 APP_LOGE("parse moduleName failed");
49 BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING);
50 return;
51 }
52
53 int32_t upgradeFlag = 0;
54 if (!EnumUtils::EnumETSToNative(env, aniUpgradeFlag, upgradeFlag)) {
55 APP_LOGE("parse upgradeFlag failed");
56 BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, UPGRADE_FLAG, TYPE_NUMBER);
57 return;
58 }
59
60 auto iBundleMgr = CommonFunc::GetBundleMgr();
61 if (iBundleMgr == nullptr) {
62 APP_LOGE("can not get iBundleMgr");
63 BusinessErrorAni::ThrowCommonError(env, ERROR_BUNDLE_SERVICE_EXCEPTION,
64 RESOURCE_NAME_OF_SET_HAP_MODULE_UPGRADE_FLAG, Constants::PERMISSION_INSTALL_BUNDLE);
65 return;
66 }
67
68 auto result = iBundleMgr->SetModuleUpgradeFlag(bundleName, moduleName, upgradeFlag);
69 if (result != ERR_OK) {
70 APP_LOGE("SetModuleUpgradeFlag failed, bundleName is %{public}s, moduleName is %{public}s", bundleName.c_str(),
71 moduleName.c_str());
72 BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(result),
73 RESOURCE_NAME_OF_SET_HAP_MODULE_UPGRADE_FLAG, Constants::PERMISSION_INSTALL_BUNDLE);
74 return;
75 }
76 }
77
AniIsHapModuleRemovable(ani_env * env,ani_string aniBundleName,ani_string aniModuleName)78 static ani_boolean AniIsHapModuleRemovable(ani_env* env, ani_string aniBundleName, ani_string aniModuleName)
79 {
80 APP_LOGD("ani IsHapModuleRemovable called");
81 std::string bundleName;
82 if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
83 APP_LOGE("parse bundleName failed");
84 BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
85 return false;
86 }
87
88 std::string moduleName;
89 if (!CommonFunAni::ParseString(env, aniModuleName, moduleName)) {
90 APP_LOGE("parse moduleName failed");
91 BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING);
92 return false;
93 }
94
95 auto iBundleMgr = CommonFunc::GetBundleMgr();
96 if (iBundleMgr == nullptr) {
97 APP_LOGE("can not get iBundleMgr");
98 BusinessErrorAni::ThrowCommonError(env, ERROR_BUNDLE_SERVICE_EXCEPTION,
99 RESOURCE_NAME_OF_IS_HAP_MODULE_REMOVABLE, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
100 }
101 bool isRemovable = false;
102 auto result = iBundleMgr->IsModuleRemovable(bundleName, moduleName, isRemovable);
103 if (result != ERR_OK) {
104 APP_LOGE("IsModuleRemovable failed, bundleName is %{public}s, moduleName is %{public}s", bundleName.c_str(),
105 moduleName.c_str());
106 BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(result),
107 RESOURCE_NAME_OF_IS_HAP_MODULE_REMOVABLE, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
108 return false;
109 }
110 return CommonFunAni::BoolToAniBoolean(isRemovable);
111 }
112
AniGetBundlePackInfo(ani_env * env,ani_string aniBundleName,ani_enum_item aniBundlePackFlag)113 static ani_object AniGetBundlePackInfo(ani_env* env, ani_string aniBundleName, ani_enum_item aniBundlePackFlag)
114 {
115 APP_LOGD("ani GetBundlePackInfo called");
116 std::string bundleName;
117 if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
118 APP_LOGE("parse bundleName failed");
119 BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
120 return nullptr;
121 }
122
123 BundlePackFlag bundlePackFlag = BundlePackFlag::GET_PACK_INFO_ALL;
124 if (!EnumUtils::EnumETSToNative(env, aniBundlePackFlag, bundlePackFlag)) {
125 APP_LOGE("parse upgradeFlag failed");
126 BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_PACK_FLAG, TYPE_NUMBER);
127 return nullptr;
128 }
129
130 auto iBundleMgr = CommonFunc::GetBundleMgr();
131 if (iBundleMgr == nullptr) {
132 APP_LOGE("can not get iBundleMgr");
133 BusinessErrorAni::ThrowCommonError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, RESOURCE_NAME_OF_GET_BUNDLE_PACK_INFO,
134 Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
135 }
136 BundlePackInfo bundlePackInfo;
137 auto result = iBundleMgr->GetBundlePackInfo(bundleName, static_cast<int32_t>(bundlePackFlag), bundlePackInfo);
138 if (result != ERR_OK) {
139 APP_LOGE("GetBundlePackInfo failed, bundleName is %{public}s", bundleName.c_str());
140 BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(result),
141 RESOURCE_NAME_OF_GET_BUNDLE_PACK_INFO, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
142 return nullptr;
143 }
144 return CommonFunAni::ConvertBundlePackInfo(env, bundlePackInfo, static_cast<uint32_t>(bundlePackFlag));
145 }
146
AniGetDispatchInfo(ani_env * env)147 static ani_object AniGetDispatchInfo(ani_env* env)
148 {
149 APP_LOGD("ani GetDispatchInfo called");
150 auto iBundleMgr = CommonFunc::GetBundleMgr();
151 if (iBundleMgr == nullptr) {
152 APP_LOGE("can not get iBundleMgr");
153 BusinessErrorAni::ThrowCommonError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, RESOURCE_NAME_OF_GET_DISPATCH_INFO,
154 Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
155 return nullptr;
156 }
157 if (!iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
158 APP_LOGE("non-system app calling system api");
159 BusinessErrorAni::ThrowCommonError(env, ERROR_NOT_SYSTEM_APP, RESOURCE_NAME_OF_GET_DISPATCH_INFO,
160 Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
161 return nullptr;
162 }
163 if (!iBundleMgr->VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
164 APP_LOGE("GetDispatchInfo failed due to permission denied");
165 BusinessErrorAni::ThrowCommonError(env, ERROR_PERMISSION_DENIED_ERROR, RESOURCE_NAME_OF_GET_DISPATCH_INFO,
166 Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
167 return nullptr;
168 }
169
170 return CommonFunAni::CreateDispatchInfo(env, DISPATCH_INFO_VERSION, DISPATCH_INFO_DISPATCH_API);
171 }
172
173 extern "C" {
ANI_Constructor(ani_vm * vm,uint32_t * result)174 ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result)
175 {
176 APP_LOGI("ANI_Constructor freeInstall called");
177 ani_env* env;
178 ani_status status = vm->GetEnv(ANI_VERSION_1, &env);
179 RETURN_ANI_STATUS_IF_NOT_OK(status, "Unsupported ANI_VERSION_1");
180
181 arkts::ani_signature::Namespace nsName = arkts::ani_signature::Builder::BuildNamespace(NS_NAME_FREEINSTALL);
182 ani_namespace kitNs = nullptr;
183 status = env->FindNamespace(nsName.Descriptor().c_str(), &kitNs);
184 if (status != ANI_OK) {
185 APP_LOGE("FindNamespace: %{public}s fail with %{public}d", NS_NAME_FREEINSTALL, status);
186 return status;
187 }
188 std::array methods = {
189 ani_native_function { "setHapModuleUpgradeFlagNative", nullptr,
190 reinterpret_cast<void*>(AniSetHapModuleUpgradeFlag) },
191 ani_native_function { "isHapModuleRemovableNative", nullptr, reinterpret_cast<void*>(AniIsHapModuleRemovable) },
192 ani_native_function { "getBundlePackInfoNative", nullptr, reinterpret_cast<void*>(AniGetBundlePackInfo) },
193 ani_native_function { "getDispatchInfoNative", nullptr, reinterpret_cast<void*>(AniGetDispatchInfo) },
194 };
195
196 status = env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size());
197 if (status != ANI_OK) {
198 APP_LOGE("Namespace_BindNativeFunctions: %{public}s fail with %{public}d", NS_NAME_FREEINSTALL, status);
199 return status;
200 }
201
202 *result = ANI_VERSION_1;
203
204 APP_LOGI("ANI_Constructor finished");
205
206 return ANI_OK;
207 }
208 }
209 } // namespace AppExecFwk
210 } // namespace OHOS
211