* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ani_signature_builder.h>
#include "app_log_wrapper.h"
#include "bundle_errors.h"
#include "business_error_ani.h"
#include "common_fun_ani.h"
#include "common_func.h"
#include "napi_constants.h"
#include "overlay_module_info.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
constexpr const char* NS_NAME_OVERLAY = "@ohos.bundle.overlay.overlay";
}
static void AniSetOverlayEnabled(ani_env *env, ani_string aniModuleName, ani_boolean aniIsEnabled)
{
APP_LOGD("ani SetOverlayEnabled called");
std::string moduleName;
if (!CommonFunAni::ParseString(env, aniModuleName, moduleName) || moduleName.empty()) {
APP_LOGE("moduleName %{public}s invalid", moduleName.c_str());
BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING);
return;
}
bool isEnabled = CommonFunAni::AniBooleanToBool(aniIsEnabled);
auto overlayMgrProxy = CommonFunc::GetOverlayMgrProxy();
if (overlayMgrProxy == nullptr) {
APP_LOGE("overlayMgrProxy is null");
BusinessErrorAni::ThrowCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
SET_OVERLAY_ENABLED, Constants::PERMISSION_CHANGE_OVERLAY_ENABLED_STATE);
return;
}
ErrCode ret = overlayMgrProxy->SetOverlayEnabledForSelf(moduleName, isEnabled);
if (ret != ERR_OK) {
APP_LOGE("SetOverlayEnabledForSelf failed ret: %{public}d", ret);
BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
SET_OVERLAY_ENABLED, Constants::PERMISSION_CHANGE_OVERLAY_ENABLED_STATE);
return;
}
}
static void AniSetOverlayEnabledByBundleName(ani_env *env,
ani_string aniBundleName, ani_string aniModuleName, ani_boolean aniIsEnabled)
{
APP_LOGD("ani SetOverlayEnabledByBundleName called");
std::string bundleName;
if (!CommonFunAni::ParseString(env, aniBundleName, bundleName) || bundleName.empty()) {
APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return;
}
std::string moduleName;
if (!CommonFunAni::ParseString(env, aniModuleName, moduleName) || moduleName.empty()) {
APP_LOGE("moduleName %{public}s invalid", moduleName.c_str());
BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING);
return;
}
bool isEnabled = CommonFunAni::AniBooleanToBool(aniIsEnabled);
auto overlayMgrProxy = CommonFunc::GetOverlayMgrProxy();
if (overlayMgrProxy == nullptr) {
APP_LOGE("overlayMgrProxy is null");
BusinessErrorAni::ThrowCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
SET_OVERLAY_ENABLED_BY_BUNDLE_NAME, Constants::PERMISSION_CHANGE_OVERLAY_ENABLED_STATE);
return;
}
ErrCode ret = overlayMgrProxy->SetOverlayEnabled(bundleName, moduleName, isEnabled);
if (ret != ERR_OK) {
APP_LOGE("SetOverlayEnabled failed ret: %{public}d", ret);
BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
SET_OVERLAY_ENABLED_BY_BUNDLE_NAME, Constants::PERMISSION_CHANGE_OVERLAY_ENABLED_STATE);
return;
}
}
static ani_object AniGetOverlayModuleInfo(ani_env *env, ani_string aniModuleName)
{
APP_LOGD("ani GetOverlayModuleInfo called");
std::string moduleName;
if (!CommonFunAni::ParseString(env, aniModuleName, moduleName) || moduleName.empty()) {
APP_LOGE("moduleName %{public}s invalid", moduleName.c_str());
BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING);
return nullptr;
}
auto overlayMgrProxy = CommonFunc::GetOverlayMgrProxy();
if (overlayMgrProxy == nullptr) {
APP_LOGE("overlayMgrProxy is null");
BusinessErrorAni::ThrowCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
GET_OVERLAY_MODULE_INFO, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
return nullptr;
}
OverlayModuleInfo overlayModuleInfo;
ErrCode ret = overlayMgrProxy->GetOverlayModuleInfo(moduleName, overlayModuleInfo);
if (ret != ERR_OK) {
APP_LOGE("GetOverlayModuleInfo failed ret: %{public}d", ret);
BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
GET_OVERLAY_MODULE_INFO, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
return nullptr;
}
return CommonFunAni::ConvertOverlayModuleInfo(env, overlayModuleInfo);
}
static ani_object AniGetTargetOverlayModuleInfos(ani_env *env, ani_string aniTargetModuleName)
{
APP_LOGD("ani GetTargetOverlayModuleInfos called");
std::string targetModuleName;
if (!CommonFunAni::ParseString(env, aniTargetModuleName, targetModuleName) || targetModuleName.empty()) {
APP_LOGE("targetModuleName %{public}s invalid", targetModuleName.c_str());
BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, TARGET_MODULE_NAME, TYPE_STRING);
return nullptr;
}
auto overlayMgrProxy = CommonFunc::GetOverlayMgrProxy();
if (overlayMgrProxy == nullptr) {
APP_LOGE("overlayMgrProxy is null");
BusinessErrorAni::ThrowCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
GET_TARGET_OVERLAY_MODULE_INFOS, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
return nullptr;
}
std::vector<OverlayModuleInfo> overlayModuleInfos;
ErrCode ret = overlayMgrProxy->GetTargetOverlayModuleInfo(targetModuleName, overlayModuleInfos);
if (ret != ERR_OK) {
APP_LOGE("GetTargetOverlayModuleInfo failed ret: %{public}d", ret);
BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
GET_TARGET_OVERLAY_MODULE_INFOS, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
return nullptr;
}
ani_object overlayModuleInfosObject = CommonFunAni::ConvertAniArray(
env, overlayModuleInfos, CommonFunAni::ConvertOverlayModuleInfo);
if (overlayModuleInfosObject == nullptr) {
APP_LOGE("nullptr overlayModuleInfosObject");
}
return overlayModuleInfosObject;
}
static ani_object AniGetOverlayModuleInfoByBundleName(ani_env *env, ani_string aniBundleName, ani_string aniModuleName)
{
APP_LOGD("ani GetOverlayModuleInfoByBundleName called");
std::string bundleName;
if (!CommonFunAni::ParseString(env, aniBundleName, bundleName) || bundleName.empty()) {
APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
std::string moduleName;
if (!CommonFunAni::ParseString(env, aniModuleName, moduleName)) {
APP_LOGI("MoudleName undefined, default query for all module OverlayModuleInfo");
}
auto overlayMgrProxy = CommonFunc::GetOverlayMgrProxy();
if (overlayMgrProxy == nullptr) {
APP_LOGE("overlayMgrProxy is null");
BusinessErrorAni::ThrowCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
GET_OVERLAY_MODULE_INFO_BY_BUNDLE_NAME, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
return nullptr;
}
std::vector<OverlayModuleInfo> overlayModuleInfos;
ErrCode ret = overlayMgrProxy->GetOverlayModuleInfoByBundleName(bundleName, moduleName, overlayModuleInfos);
if (ret != ERR_OK) {
APP_LOGE("GetOverlayModuleInfoByBundleName failed ret: %{public}d", ret);
BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
GET_OVERLAY_MODULE_INFO_BY_BUNDLE_NAME, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
return nullptr;
}
ani_object overlayModuleInfosObject = CommonFunAni::ConvertAniArray(
env, overlayModuleInfos, CommonFunAni::ConvertOverlayModuleInfo);
if (overlayModuleInfosObject == nullptr) {
APP_LOGE("nullptr overlayModuleInfosObject");
}
return overlayModuleInfosObject;
}
static ani_object AniGetTargetOverlayModuleInfosByBundleName(ani_env *env,
ani_string aniTargetBundleName, ani_string aniModuleName)
{
APP_LOGD("ani GetTargetOverlayModuleInfosByBundleName called");
std::string targetBundleName;
if (!CommonFunAni::ParseString(env, aniTargetBundleName, targetBundleName) || targetBundleName.empty()) {
APP_LOGE("targetBundleName %{public}s invalid", targetBundleName.c_str());
BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, TARGET_BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
std::string moduleName;
if (!CommonFunAni::ParseString(env, aniModuleName, moduleName)) {
APP_LOGI("MoudleName undefined, default query for all module OverlayModuleInfo");
}
auto overlayMgrProxy = CommonFunc::GetOverlayMgrProxy();
if (overlayMgrProxy == nullptr) {
APP_LOGE("overlayMgrProxy is null");
BusinessErrorAni::ThrowCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
GET_TARGET_OVERLAY_MODULE_INFOS_BY_BUNDLE_NAME, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
return nullptr;
}
std::vector<OverlayModuleInfo> overlayModuleInfos;
ErrCode ret = overlayMgrProxy->GetOverlayModuleInfoForTarget(targetBundleName, moduleName, overlayModuleInfos);
if (ret != ERR_OK) {
APP_LOGE("GetOverlayModuleInfoForTarget failed ret: %{public}d", ret);
BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
GET_TARGET_OVERLAY_MODULE_INFOS_BY_BUNDLE_NAME, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
return nullptr;
}
ani_object overlayModuleInfosObject = CommonFunAni::ConvertAniArray(
env, overlayModuleInfos, CommonFunAni::ConvertOverlayModuleInfo);
if (overlayModuleInfosObject == nullptr) {
APP_LOGE("nullptr overlayModuleInfosObject");
}
return overlayModuleInfosObject;
}
extern "C" {
ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result)
{
APP_LOGI("ANI_Constructor overlay called");
ani_env* env;
ani_status status = vm->GetEnv(ANI_VERSION_1, &env);
RETURN_ANI_STATUS_IF_NOT_OK(status, "Unsupported ANI_VERSION_1");
arkts::ani_signature::Namespace nsName = arkts::ani_signature::Builder::BuildNamespace(NS_NAME_OVERLAY);
ani_namespace kitNs = nullptr;
status = env->FindNamespace(nsName.Descriptor().c_str(), &kitNs);
if (status != ANI_OK) {
APP_LOGE("FindNamespace: %{public}s fail with %{public}d", NS_NAME_OVERLAY, status);
return status;
}
std::array methods = {
ani_native_function { "setOverlayEnabledNative", nullptr,
reinterpret_cast<void*>(AniSetOverlayEnabled) },
ani_native_function { "setOverlayEnabledByBundleNameNative", nullptr,
reinterpret_cast<void*>(AniSetOverlayEnabledByBundleName) },
ani_native_function { "getOverlayModuleInfoNative", nullptr,
reinterpret_cast<void*>(AniGetOverlayModuleInfo) },
ani_native_function { "getTargetOverlayModuleInfosNative", nullptr,
reinterpret_cast<void*>(AniGetTargetOverlayModuleInfos) },
ani_native_function { "getOverlayModuleInfoByBundleNameNative", nullptr,
reinterpret_cast<void*>(AniGetOverlayModuleInfoByBundleName) },
ani_native_function { "getTargetOverlayModuleInfosByBundleNameNative", nullptr,
reinterpret_cast<void*>(AniGetTargetOverlayModuleInfosByBundleName) }
};
status = env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size());
if (status != ANI_OK) {
APP_LOGE("Namespace_BindNativeFunctions: %{public}s fail with %{public}d", NS_NAME_OVERLAY, status);
return status;
}
*result = ANI_VERSION_1;
APP_LOGI("ANI_Constructor finished");
return ANI_OK;
}
}
}
}