From 9eac4a8c20191508c296938868a9b281ebfca894 Mon Sep 17 00:00:00 2001 From: gaochao Date: Tue, 22 Apr 2025 11:02:07 +0800 Subject: [PATCH] =?UTF-8?q?1.2=E6=8E=A5=E5=8F=A3=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: gaochao --- BUILD.gn | 13 +- bundle.json | 6 +- interfaces/ets/ani/BUILD.gn | 97 +++++++++ interfaces/ets/ani/ets/@ohos.configPolicy.ets | 183 ++++++++++++++++ .../ets/@ohos.customization.customConfig.ets | 22 ++ interfaces/ets/ani/include/ani_utils.h | 35 +++ .../ets/ani/include/config_policy_ani.h | 56 +++++ .../ets/ani/include/custom_config_ani.h | 41 ++++ interfaces/ets/ani/src/ani_utils.cpp | 122 +++++++++++ interfaces/ets/ani/src/config_policy_ani.cpp | 204 ++++++++++++++++++ interfaces/ets/ani/src/custom_config_ani.cpp | 152 +++++++++++++ 11 files changed, 928 insertions(+), 3 deletions(-) create mode 100644 interfaces/ets/ani/BUILD.gn create mode 100644 interfaces/ets/ani/ets/@ohos.configPolicy.ets create mode 100644 interfaces/ets/ani/ets/@ohos.customization.customConfig.ets create mode 100644 interfaces/ets/ani/include/ani_utils.h create mode 100644 interfaces/ets/ani/include/config_policy_ani.h create mode 100644 interfaces/ets/ani/include/custom_config_ani.h create mode 100644 interfaces/ets/ani/src/ani_utils.cpp create mode 100644 interfaces/ets/ani/src/config_policy_ani.cpp create mode 100644 interfaces/ets/ani/src/custom_config_ani.cpp diff --git a/BUILD.gn b/BUILD.gn index 2303914..11e5337 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +# Copyright (c) 2022-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 @@ -25,3 +25,14 @@ group("config_policy_components") { deps = [ "./frameworks/config_policy:configpolicy_util" ] } } + +group("ani_config_policy_components") { + if (os_level == "standard" && config_policy_api_support && support_jsapi) { + deps = [ + "./interfaces/ets/ani:configpolicy_ani", + "./interfaces/ets/ani:configPolicy_etc", + "./interfaces/ets/ani:customconfig_ani", + "./interfaces/ets/ani:custom_config_etc", + ] + } +} diff --git a/bundle.json b/bundle.json index 3be48ec..fef51e4 100644 --- a/bundle.json +++ b/bundle.json @@ -34,13 +34,15 @@ "hilog", "napi", "init", - "bounds_checking_function" + "bounds_checking_function", + "runtime_core" ], "third_party": [] }, "build": { "sub_component": [ - "//base/customization/config_policy:config_policy_components" + "//base/customization/config_policy:config_policy_components", + "//base/customization/config_policy:ani_config_policy_components" ], "inner_kits": [ { diff --git a/interfaces/ets/ani/BUILD.gn b/interfaces/ets/ani/BUILD.gn new file mode 100644 index 0000000..966fd5a --- /dev/null +++ b/interfaces/ets/ani/BUILD.gn @@ -0,0 +1,97 @@ +# 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") + + +ohos_shared_library("configpolicy_ani") { + include_dirs = [ + "include", + "../../../interfaces/inner_api/include", + "../../../frameworks/dfx/hisysevent_adapter", + ] + sources = [ + "../../../frameworks/dfx/hisysevent_adapter/hisysevent_adapter.cpp", + "./src/config_policy_ani.cpp", + "./src/ani_utils.cpp", + ] + + deps = [ "../../../frameworks/config_policy:configpolicy_util" ] + + external_deps = [ + "hilog:libhilog", + "hisysevent:libhisysevent", + "runtime_core:ani", + ] + + part_name = "config_policy" + subsystem_name = "customization" +} + +generate_static_abc("configPolicy") { + base_url = "./ets" + files = [ "./ets/@ohos.configPolicy.ets" ] + is_boot_abc = "True" + device_dst_file = "system/framework/configPolicy.abc" +} + +ohos_prebuilt_etc("configPolicy_etc") { + source = "$target_out_dir/configPolicy.abc" + module_install_dir = "framework" + part_name = "config_policy" + subsystem_name = "customization" + deps = [ ":configPolicy" ] +} + +ohos_shared_library("customconfig_ani") { + include_dirs = [ + "include", + "../../../interfaces/inner_api/include", + "../../../frameworks/dfx/hisysevent_adapter", + ] + + sources = [ + "../../../frameworks/dfx/hisysevent_adapter/hisysevent_adapter.cpp", + "./src/custom_config_ani.cpp", + "./src/ani_utils.cpp", + ] + + external_deps = [ + "ability_runtime:abilitykit_native", + "ability_runtime:app_context", + "c_utils:utils", + "hilog:libhilog", + "hisysevent:libhisysevent", + "init:libbegetutil", + "runtime_core:ani", + ] + + subsystem_name = "customization" + part_name = "config_policy" +} + +generate_static_abc("custom_config") { + base_url = "./ets" + files = [ "./ets/@ohos.customization.customConfig.ets" ] + is_boot_abc = "True" + device_dst_file = "system/framework/custom_config.abc" +} + +ohos_prebuilt_etc("custom_config_etc") { + source = "$target_out_dir/custom_config.abc" + module_install_dir = "framework" + part_name = "config_policy" + subsystem_name = "customization" + deps = [ ":custom_config" ] +} \ No newline at end of file diff --git a/interfaces/ets/ani/ets/@ohos.configPolicy.ets b/interfaces/ets/ani/ets/@ohos.configPolicy.ets new file mode 100644 index 0000000..65a6f41 --- /dev/null +++ b/interfaces/ets/ani/ets/@ohos.configPolicy.ets @@ -0,0 +1,183 @@ +/* + * 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. + */ +import { AsyncCallback, BusinessError } from '@ohos.base'; + +namespace configPolicy { + + loadLibrary("configpolicy_ani.z"); + + export enum FollowXMode { + DEFAULT = 0, + NO_RULE_FOLLOWED = 1, + SIM_DEFAULT = 10, + SIM_1 = 11, + SIM_2 = 12, + USER_DEFINED = 100 + } + + native function getOneCfgFileSync(relPath: string, followMode?: FollowXMode, extra?: string): string; + + native function getCfgFilesSync(relPath: string, followMode?: FollowXMode, extra?: string): Array; + + native function getCfgDirListSync(): Array; + + function getOneCfgFile(relPath: string, callback: AsyncCallback) : void { + taskpool.execute((): string => { + return getOneCfgFileSync(relPath); + }).then((content: NullishType) => { + let error = new BusinessError + error.code = 0 + callback(error, content as string); + }).catch((err: NullishType) : void => { + callback(err as BusinessError, ""); + }); + } + + function getOneCfgFile(relPath: string, followMode: FollowXMode, callback: AsyncCallback) : void { + taskpool.execute((): string => { + return getOneCfgFileSync(relPath, followMode); + }).then((content: NullishType) => { + let error = new BusinessError + error.code = 0 + callback(error, content as string); + }).catch((err: NullishType) : void => { + callback(err as BusinessError, ""); + }); + } + + function getOneCfgFile( + relPath: string, followMode: FollowXMode, extra: string, callback: AsyncCallback) : void { + taskpool.execute((): string => { + return getOneCfgFileSync(relPath, followMode, extra); + }).then((content: NullishType) => { + let error = new BusinessError + error.code = 0 + callback(error, content as string); + }).catch((err: NullishType) : void => { + callback(err as BusinessError, ""); + }); + } + + function getOneCfgFile(relPath: string): Promise { + return new Promise((resolve, reject) => { + taskpool.execute((): string => { + return getOneCfgFileSync(relPath); + }).then((content: NullishType) => { + resolve(content as string); + }, (err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + function getOneCfgFile(relPath: string, followMode: FollowXMode, extra?: string): Promise { + return new Promise((resolve, reject) => { + taskpool.execute((): string => { + return getOneCfgFileSync(relPath, followMode, extra); + }).then((content: NullishType) => { + resolve(content as string); + }, (err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + function getCfgFiles(relPath: string, callback: AsyncCallback>) : void { + taskpool.execute((): Array => { + return getCfgFilesSync(relPath); + }).then((content: NullishType) => { + let error = new BusinessError + error.code = 0 + callback(error, content as Array); + }).catch((err: NullishType) : void => { + callback(err as BusinessError, new Array); + }); + } + + function getCfgFiles(relPath: string, followMode: FollowXMode, callback: AsyncCallback>) : void { + taskpool.execute((): Array => { + return getCfgFilesSync(relPath, followMode); + }).then((content: NullishType) => { + let error = new BusinessError + error.code = 0 + callback(error, content as Array); + }).catch((err: NullishType) : void => { + callback(err as BusinessError, new Array); + }); + } + + function getCfgFiles( + relPath: string, followMode: FollowXMode, extra: string, callback: AsyncCallback>) : void { + taskpool.execute((): Array => { + return getCfgFilesSync(relPath, followMode, extra); + }).then((content: NullishType) => { + let error = new BusinessError + error.code = 0 + callback(error, content as Array); + }).catch((err: NullishType) : void => { + callback(err as BusinessError, new Array); + }); + } + + function getCfgFiles(relPath: string): Promise> { + return new Promise>((resolve, reject) => { + taskpool.execute((): Array => { + return getCfgFilesSync(relPath); + }).then((content: NullishType) => { + resolve(content as Array); + }, (err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + function getCfgFiles(relPath: string, followMode: FollowXMode, extra?: string): Promise> { + return new Promise>((resolve, reject) => { + taskpool.execute((): Array => { + return getCfgFilesSync(relPath, followMode, extra); + }).then((content: NullishType) => { + resolve(content as Array); + }, (err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + function getCfgDirList(callback: AsyncCallback>) : void { + taskpool.execute((): Array => { + return getCfgDirListSync(); + }).then((content: NullishType) => { + let error = new BusinessError + error.code = 0 + callback(error, content as Array); + }).catch((err: NullishType) : void => { + callback(err as BusinessError, new Array); + }); + } + + function getCfgDirList(): Promise> { + return new Promise>((resolve, reject) => { + taskpool.execute((): Array => { + return getCfgDirListSync(); + }).then((content: NullishType) => { + resolve(content as Array); + }, (err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } +} + +export default configPolicy; diff --git a/interfaces/ets/ani/ets/@ohos.customization.customConfig.ets b/interfaces/ets/ani/ets/@ohos.customization.customConfig.ets new file mode 100644 index 0000000..83939ff --- /dev/null +++ b/interfaces/ets/ani/ets/@ohos.customization.customConfig.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +namespace customConfig { + loadLibrary("customconfig_ani.z"); + + native function getChannelId(): string; +} + +export default customConfig; diff --git a/interfaces/ets/ani/include/ani_utils.h b/interfaces/ets/ani/include/ani_utils.h new file mode 100644 index 0000000..8b7cd54 --- /dev/null +++ b/interfaces/ets/ani/include/ani_utils.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + +#ifndef ANI_UTILS_H +#define ANI_UTILS_H + +#include +#include + +namespace OHOS { +namespace Customization { +namespace ConfigPolicy { +class AniUtils { +public: + static bool AniStrToString(ani_env *env, ani_string ani_str, std::string& out); + static ani_string StringToAniStr(ani_env *env, const std::string &str); + static ani_ref CreateAniStringArray(ani_env *env, const std::vector &paths); + static void ThrowAniError(ani_env *env, int32_t code, const std::string &message); +}; +} // namespace ConfigPolicy +} // namespace Customization +} // namespace OHOS +#endif diff --git a/interfaces/ets/ani/include/config_policy_ani.h b/interfaces/ets/ani/include/config_policy_ani.h new file mode 100644 index 0000000..38f0d3a --- /dev/null +++ b/interfaces/ets/ani/include/config_policy_ani.h @@ -0,0 +1,56 @@ +/* + * 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. + */ + +#ifndef CONFIG_POLICY_ANI_H +#define CONFIG_POLICY_ANI_H + +#include +#include + +namespace OHOS { +namespace Customization { +namespace ConfigPolicy { + +struct ConfigSyncContext { + std::string relPath; + int32_t followMode; + std::string extra; +}; + +class ConfigPolicyAni { +public: + ConfigPolicyAni(); + ~ConfigPolicyAni() = default; + static ani_status Init(ani_env* vm); +private: + + static ani_string GetOneCfgFileSync(ani_env* env, ani_string relPath, ani_enum_item followMode, ani_string extra); + + static ani_ref GetCfgFilesSync(ani_env* env, ani_string relPath, ani_enum_item followMode, ani_string extra); + + static ani_ref GetCfgDirListSync(ani_env* env); + + static bool TransformParams( + ani_env* env, ani_string relPath, ani_enum_item followMode, ani_string extra, ConfigSyncContext& context); + + static bool ParseFollowMode( + ani_env* env, ani_enum_item followMode, ConfigSyncContext& context, bool hasExtra); + + static bool ParseExtra(ani_env* env, ani_string extra, ConfigSyncContext& context); +}; +} // namespace ConfigPolicy +} // namespace Customization +} // namespace OHOS +#endif diff --git a/interfaces/ets/ani/include/custom_config_ani.h b/interfaces/ets/ani/include/custom_config_ani.h new file mode 100644 index 0000000..7439c8e --- /dev/null +++ b/interfaces/ets/ani/include/custom_config_ani.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +#ifndef CUSTOM_CONFIG_ANI_H +#define CUSTOM_CONFIG_ANI_H + +#include + +#include + +namespace OHOS { +namespace Customization { +namespace ConfigPolicy { +class CustomConfigAni { +public: + CustomConfigAni(); + ~CustomConfigAni() = default; + static ani_status Init(ani_env* vm); + +private: + static ani_string GetChannelId(ani_env* env); + static int GetBundleName(std::string &bundleName); + static bool IsInPreloadList(std::string bundleName); + static char* CustGetSystemParam(const char *name); +}; +} // namespace ConfigPolicy +} // namespace Customization +} // namespace OHOS +#endif diff --git a/interfaces/ets/ani/src/ani_utils.cpp b/interfaces/ets/ani/src/ani_utils.cpp new file mode 100644 index 0000000..a41cfbf --- /dev/null +++ b/interfaces/ets/ani/src/ani_utils.cpp @@ -0,0 +1,122 @@ +/* + * 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_utils.h" +#include "hilog/log.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN 0xD001E00 + +#undef LOG_TAG +#define LOG_TAG "ConfigPolicyJs" + +namespace OHOS { +namespace Customization { +namespace ConfigPolicy { +static const char* CLASS_NAME_BUSINESSERROR = "L@ohos/base/BusinessError;"; +static const char* CLASS_NAME_STRING = "Lstd/core/String;"; + +bool AniUtils::AniStrToString(ani_env *env, ani_string ani_str, std::string& out) +{ + ani_size strSize; + if (env->String_GetUTF8Size(ani_str, &strSize) != ANI_OK) { + return false; + } + + std::vector buffer(strSize + 1); // +1 for null terminator + char *utf8_buffer = buffer.data(); + + ani_size bytes_written = 0; + if (env->String_GetUTF8(ani_str, utf8_buffer, strSize + 1, &bytes_written) != ANI_OK) { + return false; + } + + utf8_buffer[bytes_written] = '\0'; + out = std::string(utf8_buffer); + return true; +} + +ani_string AniUtils::StringToAniStr(ani_env *env, const std::string &str) +{ + ani_string result{}; + if (ANI_OK != env->String_NewUTF8(str.c_str(), str.size(), &result)) { + return nullptr; + } + return result; +} + +ani_ref AniUtils::CreateAniStringArray(ani_env *env, const std::vector &paths) +{ + ani_class stringCls = nullptr; + if (ANI_OK != env->FindClass(CLASS_NAME_STRING, &stringCls)) { + HILOG_ERROR(LOG_CORE, "find class %{public}s failed", CLASS_NAME_STRING); + } + + ani_ref undefinedRef = nullptr; + if (ANI_OK != env->GetUndefined(&undefinedRef)) { + HILOG_ERROR(LOG_CORE, "GetUndefined Failed."); + } + + ani_array_ref array; + if (ANI_OK != env->Array_New_Ref(stringCls, paths.size(), undefinedRef, &array)) { + HILOG_ERROR(LOG_CORE, "new array ref error."); + return array; + } + for (size_t i = 0; i < paths.size(); ++i) { + auto item = AniUtils::StringToAniStr(env, paths[i]); + if (ANI_OK != env->Array_Set_Ref(array, i, item)) { + return array; + } + } + return array; +} + +void AniUtils::ThrowAniError(ani_env *env, int32_t code, const std::string &message) +{ + ani_class cls {}; + if (ANI_OK != env->FindClass(CLASS_NAME_BUSINESSERROR, &cls)) { + HILOG_ERROR(LOG_CORE, "find class %{public}s failed", CLASS_NAME_BUSINESSERROR); + return; + } + ani_method ctor {}; + if (ANI_OK != env->Class_FindMethod(cls, "", ":V", &ctor)) { + HILOG_ERROR(LOG_CORE, "find method BusinessError constructor failed"); + return; + } + ani_object error {}; + if (ANI_OK != env->Object_New(cls, ctor, &error)) { + HILOG_ERROR(LOG_CORE, "new object %{public}s failed", CLASS_NAME_BUSINESSERROR); + return; + } + if (ANI_OK != env->Object_SetPropertyByName_Double(error, "code", static_cast(code))) { + HILOG_ERROR(LOG_CORE, "set property BusinessError.code failed"); + return; + } + ani_string messageRef {}; + if (ANI_OK != env->String_NewUTF8(message.c_str(), message.size(), &messageRef)) { + HILOG_ERROR(LOG_CORE, "new message string failed"); + return; + } + if (ANI_OK != env->Object_SetPropertyByName_Ref(error, "message", static_cast(messageRef))) { + HILOG_ERROR(LOG_CORE, "set property BusinessError.message failed"); + return; + } + if (ANI_OK != env->ThrowError(static_cast(error))) { + HILOG_ERROR(LOG_CORE, "throwError ani_error object failed"); + } +} +} // namespace ConfigPolicy +} // namespace Customization +} // namespace OHOS diff --git a/interfaces/ets/ani/src/config_policy_ani.cpp b/interfaces/ets/ani/src/config_policy_ani.cpp new file mode 100644 index 0000000..375e532 --- /dev/null +++ b/interfaces/ets/ani/src/config_policy_ani.cpp @@ -0,0 +1,204 @@ +/* + * 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 "config_policy_ani.h" + +#include +#include +#include "hilog/log.h" +#include "config_policy_utils.h" +#include "hisysevent_adapter.h" +#include "ani_utils.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN 0xD001E00 + +#undef LOG_TAG +#define LOG_TAG "ConfigPolicyJs" + +namespace OHOS { +namespace Customization { +namespace ConfigPolicy { +using namespace OHOS::HiviewDFX; + +static const char* NAMESPACE_NAME = "L@ohos/configPolicy/configPolicy;"; + +// Param Error Code +static constexpr int32_t PARAM_ERROR = 401; + +ani_status ConfigPolicyAni::Init(ani_env* env) +{ + ani_namespace ns; + if (ANI_OK != env->FindNamespace(NAMESPACE_NAME, &ns)) { + HILOG_ERROR(LOG_CORE, "Not found namespace %{public}s.", NAMESPACE_NAME); + return ANI_ERROR; + } + std::array methods = { + ani_native_function { "getOneCfgFileSync", nullptr, reinterpret_cast(GetOneCfgFileSync) }, + ani_native_function { "getCfgFilesSync", nullptr, reinterpret_cast(GetCfgFilesSync) }, + ani_native_function { "getCfgDirListSync", nullptr, reinterpret_cast(GetCfgDirListSync) }, + }; + if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) { + HILOG_ERROR(LOG_CORE, "Cannot bind native methods to namespace[%{public}s]", NAMESPACE_NAME); + return ANI_ERROR; + }; + return ANI_OK; +} + +bool ConfigPolicyAni::TransformParams( + ani_env* env, ani_string relPath, ani_enum_item followMode, ani_string extra, ConfigSyncContext& context) +{ + if (!AniUtils::AniStrToString(env, relPath, context.relPath)) { + HILOG_ERROR(LOG_CORE, "parse relPath error."); + return false; + } + ani_boolean modeIsUndefined; + auto followModeRet = env->Reference_IsUndefined(followMode, &modeIsUndefined); + if (followModeRet != ANI_OK || modeIsUndefined) { + return true; + } + ani_boolean extraIsUndefined; + auto extraRet = env->Reference_IsUndefined(extra, &extraIsUndefined); + if (extraRet != ANI_OK || extraIsUndefined) { + return ParseFollowMode(env, followMode, context, false); + } + return ParseFollowMode(env, followMode, context, true) && ParseExtra(env, extra, context); +} + +bool ConfigPolicyAni::ParseFollowMode( + ani_env* env, ani_enum_item followMode, ConfigSyncContext& context, bool hasExtra) +{ + ani_int enumValue; + if (ANI_OK != env->EnumItem_GetValue_Int(followMode, &enumValue)) { + AniUtils::ThrowAniError(env, PARAM_ERROR, "Parameter error. The type of followMode must be number."); + return false; + } + switch (enumValue) { + case FOLLOWX_MODE_DEFAULT: + [[fallthrough]]; + case FOLLOWX_MODE_NO_RULE_FOLLOWED: + [[fallthrough]]; + case FOLLOWX_MODE_SIM_DEFAULT: + [[fallthrough]]; + case FOLLOWX_MODE_SIM_1: + [[fallthrough]]; + case FOLLOWX_MODE_SIM_2: + break; + case FOLLOWX_MODE_USER_DEFINED: + if (!hasExtra) { + AniUtils::ThrowAniError(env, PARAM_ERROR, + "Parameter error. The followMode is USER_DEFINED, extra must be set."); + return false; + } + break; + default: + AniUtils::ThrowAniError(env, PARAM_ERROR, + "Parameter error. The value of followMode should be in the enumeration value of FollowXMode."); + return false; + } + context.followMode = enumValue; + return true; +} + +bool ConfigPolicyAni::ParseExtra(ani_env* env, ani_string extra, ConfigSyncContext& context) +{ + return AniUtils::AniStrToString(env, extra, context.extra); +} + +ani_string ConfigPolicyAni::GetOneCfgFileSync( + ani_env* env, ani_string relPath, ani_enum_item followMode, ani_string extra) +{ + HILOG_DEBUG(LOG_CORE, "NativeGetOneCfgFileSync start."); + ConfigSyncContext context; + context.followMode = FOLLOWX_MODE_DEFAULT; + if (!TransformParams(env, relPath, followMode, extra, context)) { + HILOG_ERROR(LOG_CORE, "trans form params error."); + return AniUtils::StringToAniStr(env, ""); + } + char outBuf[MAX_PATH_LEN] = {0}; + char *filePath = GetOneCfgFileEx( + context.relPath.c_str(), outBuf, MAX_PATH_LEN, context.followMode, context.extra.c_str()); + std::string result; + if (filePath == nullptr) { + HILOG_DEBUG(LOG_CORE, "GetOneCfgFileEx result is nullptr."); + ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_FAILED, "getOneCfgFileSync", "CfgFile path is nullptr."); + } else { + result = std::string(filePath); + } + return AniUtils::StringToAniStr(env, result); +} + +ani_ref ConfigPolicyAni::GetCfgFilesSync(ani_env* env, ani_string relPath, ani_enum_item followMode, ani_string extra) +{ + HILOG_DEBUG(LOG_CORE, "NativeGetCfgFiles start."); + std::vector paths; + ConfigSyncContext context; + context.followMode = FOLLOWX_MODE_DEFAULT; + if (!TransformParams(env, relPath, followMode, extra, context)) { + HILOG_ERROR(LOG_CORE, "trans form params error."); + return AniUtils::CreateAniStringArray(env, paths); + } + CfgFiles *cfgFiles = GetCfgFilesEx(context.relPath.c_str(), context.followMode, context.extra.c_str()); + if (cfgFiles == nullptr) { + HILOG_DEBUG(LOG_CORE, "GetCfgFilesSync result is nullptr."); + ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_FAILED, "getCfgFilesSync", "CfgFiles is nullptr."); + return AniUtils::CreateAniStringArray(env, paths); + } + for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) { + if (cfgFiles->paths[i] != nullptr) { + paths.push_back(cfgFiles->paths[i]); + } + } + FreeCfgFiles(cfgFiles); + return AniUtils::CreateAniStringArray(env, paths); +} + +ani_ref ConfigPolicyAni::GetCfgDirListSync(ani_env* env) +{ + HILOG_DEBUG(LOG_CORE, "NativeGetCfgDirListSync start."); + std::vector paths; + CfgDir *cfgDir = GetCfgDirList(); + if (cfgDir == nullptr) { + HILOG_DEBUG(LOG_CORE, "GetCfgDirList result is nullptr."); + ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_FAILED, "getCfgDirListSync", "CfgDirList is nullptr."); + return AniUtils::CreateAniStringArray(env, paths); + } + for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) { + if (cfgDir->paths[i] != nullptr) { + paths.push_back(cfgDir->paths[i]); + } + } + FreeCfgDirList(cfgDir); + return AniUtils::CreateAniStringArray(env, paths); +} +} // namespace ConfigPolicy +} // namespace Customization +} // namespace OHOS + +ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) +{ + ani_env* env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + HILOG_ERROR(LOG_CORE, "Unsupported ANI_VERSION_1."); + return (ani_status)ANI_ERROR; + } + + auto status = OHOS::Customization::ConfigPolicy::ConfigPolicyAni::Init(env); + if (status != ANI_OK) { + return status; + } + *result = ANI_VERSION_1; + return ANI_OK; +} diff --git a/interfaces/ets/ani/src/custom_config_ani.cpp b/interfaces/ets/ani/src/custom_config_ani.cpp new file mode 100644 index 0000000..d91d67f --- /dev/null +++ b/interfaces/ets/ani/src/custom_config_ani.cpp @@ -0,0 +1,152 @@ +/* + * 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 "custom_config_ani.h" + +#include "application_context.h" +#include "hilog/log.h" +#include "hisysevent_adapter.h" +#include "init_param.h" +#include "ani_utils.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN 0xD001E00 + +#undef LOG_TAG +#define LOG_TAG "CustomConfigJs" + +namespace OHOS { +namespace Customization { +namespace ConfigPolicy { +using namespace OHOS::HiviewDFX; + +static const char* NAMESPACE_NAME = "L@ohos/customization/customConfig/customConfig;"; +static const std::string CHANNEL_ID_PREFIX = "const.channelid."; +static const std::string CUSTOM_PRELOAD_LIST_PARA = "persist.custom.preload.list"; + +ani_status CustomConfigAni::Init(ani_env* env) +{ + ani_namespace ns; + if (ANI_OK != env->FindNamespace(NAMESPACE_NAME, &ns)) { + HILOG_ERROR(LOG_CORE, "Not found namespace %{public}s.", NAMESPACE_NAME); + return ANI_ERROR; + } + std::array methods = { + ani_native_function { "getChannelId", nullptr, reinterpret_cast(GetChannelId) }, + }; + if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) { + HILOG_ERROR(LOG_CORE, "Cannot bind native methods to namespace[%{public}s]", NAMESPACE_NAME); + return ANI_ERROR; + }; + return ANI_OK; +} + +int CustomConfigAni::GetBundleName(std::string &bundleName) +{ + std::shared_ptr abilityContext = + AbilityRuntime::Context::GetApplicationContext(); + if (abilityContext == nullptr) { + HILOG_ERROR(LOG_CORE, "get abilityContext failed."); + return -1; + } + bundleName = abilityContext->GetBundleName(); + return 0; +} + +bool CustomConfigAni::IsInPreloadList(std::string bundleName) +{ + char *preloadList = CustGetSystemParam(CUSTOM_PRELOAD_LIST_PARA.c_str()); + if (preloadList == nullptr) { + HILOG_WARN(LOG_CORE, "get preload list fail."); + return false; + } + if (preloadList[0] < '0' || preloadList[0] > '9' || preloadList[1] != ',') { + HILOG_ERROR(LOG_CORE, "preload list param format error."); + free(preloadList); + return false; + } + int listlen = preloadList[0] - '0'; + std::string preloadListResult(preloadList + 1); // skip listlen + free(preloadList); + + for (int i = 1; i < listlen; i++) { + std::string tempPreloadListPara = CUSTOM_PRELOAD_LIST_PARA + std::to_string(i); + char *tempList = CustGetSystemParam(tempPreloadListPara.c_str()); + if (tempList == nullptr) { + HILOG_ERROR(LOG_CORE, "preload list len error."); + return false; + } + preloadListResult.append(tempList + 1); // skip listlen + free(tempList); + } + preloadListResult.append(","); + return preloadListResult.find("," + bundleName + ",") != std::string::npos; +} + +char* CustomConfigAni::CustGetSystemParam(const char *name) +{ + char *value = nullptr; + unsigned int len = 0; + + if (SystemGetParameter(name, nullptr, &len) != 0 || len <= 0 || len > PARAM_CONST_VALUE_LEN_MAX) { + return nullptr; + } + value = (char *)calloc(len, sizeof(char)); + if (value != nullptr && SystemGetParameter(name, value, &len) == 0 && value[0]) { + return value; + } + if (value != nullptr) { + free(value); + } + return nullptr; +} + +ani_string CustomConfigAni::GetChannelId(ani_env* env) +{ + std::string bundleName; + if (GetBundleName(bundleName) != 0 || bundleName.empty() || IsInPreloadList(bundleName)) { + return AniUtils::StringToAniStr(env, ""); + } + std::string channelKey = CHANNEL_ID_PREFIX + bundleName; + char *channelId = CustGetSystemParam(channelKey.c_str()); + if (channelId == nullptr) { + HILOG_WARN(LOG_CORE, "get channelId failed."); + ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_FAILED, "getChannelId", "ChannelId is nullptr."); + return AniUtils::StringToAniStr(env, ""); + } + std::string channelIdStr(channelId); + ani_string result = AniUtils::StringToAniStr(env, channelIdStr); + free(channelId); + return result; +} +} // namespace ConfigPolicy +} // namespace Customization +} // namespace OHOS + +ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) +{ + ani_env* env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + HILOG_ERROR(LOG_CORE, "Unsupported ANI_VERSION_1."); + return (ani_status)ANI_ERROR; + } + + auto status = OHOS::Customization::ConfigPolicy::CustomConfigAni::Init(env); + if (status != ANI_OK) { + return status; + } + *result = ANI_VERSION_1; + return ANI_OK; +} -- Gitee