merge master into master

cust 强基需求回合

Created-by: jckon
Commit-by: jckon;sunjie
Merged-by: openharmony_ci
Description: ### 相关的Issue

  
### 原因(目的、解决的问题等)


### 描述(做了什么,变更了什么)


### 测试用例(新增、改动、可能影响的功能)
    
    
### L0新增用例自检结果
- [ ] 是,有新增L0用例,且完成自检
- [x] 否


See merge request: openharmony/customization_config_policy!171
This commit is contained in:
openharmony_ci
2025-09-19 16:20:47 +08:00
11 changed files with 909 additions and 3 deletions
+12 -1
View File
@@ -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_etc",
"./interfaces/ets/ani:configpolicy_ani",
"./interfaces/ets/ani:custom_config_etc",
"./interfaces/ets/ani:customconfig_ani",
]
}
}
+4 -2
View File
@@ -35,13 +35,15 @@
"napi",
"init",
"bounds_checking_function",
"ipc"
"ipc",
"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": [
{
+98
View File
@@ -0,0 +1,98 @@
# 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") {
shlib_type = "ani"
include_dirs = [
"include",
"../../../interfaces/inner_api/include",
"../../../frameworks/dfx/hisysevent_adapter",
]
sources = [
"../../../frameworks/dfx/hisysevent_adapter/hisysevent_adapter.cpp",
"./src/ani_utils.cpp",
"./src/config_policy_ani.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") {
shlib_type = "ani"
include_dirs = [
"include",
"../../../interfaces/inner_api/include",
"../../../frameworks/dfx/hisysevent_adapter",
]
sources = [
"../../../frameworks/dfx/hisysevent_adapter/hisysevent_adapter.cpp",
"./src/ani_utils.cpp",
"./src/custom_config_ani.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" ]
}
@@ -0,0 +1,169 @@
/*
* 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<string>;
native function getCfgDirListSync(): Array<string>;
function getOneCfgFile(relPath: string, callback: AsyncCallback<string>) : void {
taskpool.execute((): string => {
return getOneCfgFileSync(relPath);
}).then((content: NullishType) => {
callback(null, content as string);
}).catch((err: NullishType) : void => {
callback(err as BusinessError, undefined);
});
}
function getOneCfgFile(relPath: string, followMode: FollowXMode, callback: AsyncCallback<string>) : void {
taskpool.execute((): string => {
return getOneCfgFileSync(relPath, followMode);
}).then((content: NullishType) => {
callback(null, content as string);
}).catch((err: NullishType) : void => {
callback(err as BusinessError, undefined);
});
}
function getOneCfgFile(
relPath: string, followMode: FollowXMode, extra: string, callback: AsyncCallback<string>) : void {
taskpool.execute((): string => {
return getOneCfgFileSync(relPath, followMode, extra);
}).then((content: NullishType) => {
callback(null, content as string);
}).catch((err: NullishType) : void => {
callback(err as BusinessError, undefined);
});
}
function getOneCfgFile(relPath: string): Promise<string> {
return new Promise<string>((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<string> {
return new Promise<string>((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<Array<string>>) : void {
taskpool.execute((): Array<string> => {
return getCfgFilesSync(relPath);
}).then((content: NullishType) => {
callback(null, content as Array<string>);
}).catch((err: NullishType) : void => {
callback(err as BusinessError, undefined);
});
}
function getCfgFiles(relPath: string, followMode: FollowXMode, callback: AsyncCallback<Array<string>>) : void {
taskpool.execute((): Array<string> => {
return getCfgFilesSync(relPath, followMode);
}).then((content: NullishType) => {
callback(null, content as Array<string>);
}).catch((err: NullishType) : void => {
callback(err as BusinessError, undefined);
});
}
function getCfgFiles(
relPath: string, followMode: FollowXMode, extra: string, callback: AsyncCallback<Array<string>>) : void {
taskpool.execute((): Array<string> => {
return getCfgFilesSync(relPath, followMode, extra);
}).then((content: NullishType) => {
callback(null, content as Array<string>);
}).catch((err: NullishType) : void => {
callback(err as BusinessError, undefined);
});
}
function getCfgFiles(relPath: string): Promise<Array<string>> {
return new Promise<Array<string>>((resolve, reject) => {
taskpool.execute((): Array<string> => {
return getCfgFilesSync(relPath);
}).then((content: NullishType) => {
resolve(content as Array<string>);
}, (err: NullishType): void => {
reject(err as BusinessError);
});
});
}
function getCfgFiles(relPath: string, followMode: FollowXMode, extra?: string): Promise<Array<string>> {
return new Promise<Array<string>>((resolve, reject) => {
taskpool.execute((): Array<string> => {
return getCfgFilesSync(relPath, followMode, extra);
}).then((content: NullishType) => {
resolve(content as Array<string>);
}, (err: NullishType): void => {
reject(err as BusinessError);
});
});
}
function getCfgDirList(callback: AsyncCallback<Array<string>>) : void {
taskpool.execute((): Array<string> => {
return getCfgDirListSync();
}).then((content: NullishType) => {
callback(null, content as Array<string>);
}).catch((err: NullishType) : void => {
callback(err as BusinessError, undefined);
});
}
function getCfgDirList(): Promise<Array<string>> {
return new Promise<Array<string>>((resolve, reject) => {
taskpool.execute((): Array<string> => {
return getCfgDirListSync();
}).then((content: NullishType) => {
resolve(content as Array<string>);
}, (err: NullishType): void => {
reject(err as BusinessError);
});
});
}
}
export default configPolicy;
@@ -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;
+35
View File
@@ -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 <ani.h>
#include <string>
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<std::string> &paths);
static void ThrowAniError(ani_env *env, int32_t code, const std::string &message);
};
} // namespace ConfigPolicy
} // namespace Customization
} // namespace OHOS
#endif
@@ -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 <ani.h>
#include <string>
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
@@ -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 <string>
#include <ani.h>
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
+116
View File
@@ -0,0 +1,116 @@
/*
* 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 = "@ohos.base.BusinessError";
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<char> 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<std::string> &paths)
{
ani_ref undefinedRef = nullptr;
if (ANI_OK != env->GetUndefined(&undefinedRef)) {
HILOG_ERROR(LOG_CORE, "GetUndefined Failed.");
}
ani_array array;
if (ANI_OK != env->Array_New(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(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, "<ctor>", ":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_Int(error, "code", static_cast<ani_int>(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<ani_ref>(messageRef))) {
HILOG_ERROR(LOG_CORE, "set property BusinessError.message failed");
return;
}
if (ANI_OK != env->ThrowError(static_cast<ani_error>(error))) {
HILOG_ERROR(LOG_CORE, "throwError ani_error object failed");
}
}
} // namespace ConfigPolicy
} // namespace Customization
} // namespace OHOS
@@ -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 <vector>
#include <string>
#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 = "@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<void*>(GetOneCfgFileSync) },
ani_native_function { "getCfgFilesSync", nullptr, reinterpret_cast<void*>(GetCfgFilesSync) },
ani_native_function { "getCfgDirListSync", nullptr, reinterpret_cast<void*>(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<std::string> 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<std::string> 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;
}
@@ -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 = "@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<void*>(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<AbilityRuntime::ApplicationContext> 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;
}