diff --git a/bundle.json b/bundle.json index 44c9441c6910cd4639418e28cdddcd6bc4da2971..5e16fc0055c0c4a1d6765a91f99f2e69f311e370 100644 --- a/bundle.json +++ b/bundle.json @@ -27,7 +27,8 @@ "ffrt", "init", "napi", - "zlib" + "zlib", + "runtime_core" ] }, "features": [ @@ -41,7 +42,8 @@ "//base/hiviewdfx/hilog/frameworks/hilog_ndk:hilog_ndk", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_base", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", - "//base/hiviewdfx/hilog/interfaces/rust:hilog_rust" + "//base/hiviewdfx/hilog/interfaces/rust:hilog_rust", + "//base/hiviewdfx/hilog/interfaces/ets/ani:ani_hilog_package" ], "inner_kits": [ { diff --git a/interfaces/ets/ani/BUILD.gn b/interfaces/ets/ani/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..2f7c2ab20cb9143e5492aaa581a9e38335acd4df --- /dev/null +++ b/interfaces/ets/ani/BUILD.gn @@ -0,0 +1,24 @@ +# 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/ohos.gni") + +group("ani_hilog_package") { + deps = [] + if (support_jsapi) { + deps += [ + "hilog:hilog_ani", + "hilog:hilog_etc", + ] + } +} diff --git a/interfaces/ets/ani/hilog/BUILD.gn b/interfaces/ets/ani/hilog/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..f9d188c5e0e3c20955fa3a3986d4d894f0dd3f85 --- /dev/null +++ b/interfaces/ets/ani/hilog/BUILD.gn @@ -0,0 +1,71 @@ +# 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("//base/hiviewdfx/hilog/hilog.gni") +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") + +ohos_shared_library("hilog_ani") { + include_dirs = [ "./include" ] + sources = [ "./src/hilog_ani.cpp" ] + configs = [ "../../../../frameworks/libhilog:libhilog_config" ] + + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + deps = [] + + external_deps = [ + "bounds_checking_function:libsec_shared", + "runtime_core:ani", + "runtime_core:libarkruntime", + ] + + if (!is_mingw && !is_mac && !is_linux) { + deps += [ "../../../native/innerkits:libhilog" ] + } + + cflags_cc = [] + if (is_mingw) { + deps += [ "../../../native/innerkits:libhilog_windows" ] + defines += [ "__WINDOWS__" ] + cflags_cc += [ "-std=c++17" ] + } else if (is_mac) { + deps += [ "../../../native/innerkits:libhilog_mac" ] + defines += [ "__MAC__" ] + } else if (is_linux) { + deps += [ "../../../native/innerkits:libhilog_linux" ] + defines += [ "__LINUX__" ] + } + + subsystem_name = "hiviewdfx" + part_name = "hilog" + output_extension = "so" +} + +generate_static_abc("hilog") { + base_url = "./ets" + files = [ "./ets/@ohos.hilog.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/hilog.abc" +} + +ohos_prebuilt_etc("hilog_etc") { + source = "$target_out_dir/hilog.abc" + module_install_dir = "framework" + subsystem_name = "hiviewdfx" + part_name = "hilog" + deps = [ ":hilog" ] +} diff --git a/interfaces/ets/ani/hilog/ets/@ohos.hilog.ets b/interfaces/ets/ani/hilog/ets/@ohos.hilog.ets new file mode 100644 index 0000000000000000000000000000000000000000..41241450d5cd1db677da3497ffe3053dbf4cd65c --- /dev/null +++ b/interfaces/ets/ani/hilog/ets/@ohos.hilog.ets @@ -0,0 +1,93 @@ +/* + * 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. + */ + +class hilogAni { + native static debug(domain: number, tag: string, format: string, + args: Array): void; + native static info(domain: number, tag: string, format: string, + args: Array): void; + native static warn(domain: number, tag: string, format: string, + args: Array): void; + native static error(domain: number, tag: string, format: string, + args: Array): void; + native static fatal(domain: number, tag: string, format: string, + args: Array): void; + native static isLoggable(domain: number, tag: string, level: hilog.LogLevel): boolean; +} + +export default namespace hilog { + loadLibrary("hilog_ani"); + export enum LogLevel { + DEBUG = 3, + INFO = 4, + WARN = 5, + ERROR = 6, + FATAL = 7 + } + + export function debug(domain: number, tag: string, format: string, + ...args: (int | boolean | number | string | bigint | undefined)[]): void { + let arr: Array = {} + for (let i = 0; i < args.length; i++) { + arr.push(args[i]) + } + const args_casted = arr as (Array) + hilogAni.debug(domain, tag, format, arr) + } + + export function info(domain: number, tag: string, format: string, + ...args: (int | boolean | number | string | bigint | undefined)[]): void { + let arr: Array = {} + for (let i = 0; i < args.length; i++) { + arr.push(args[i]) + } + const args_casted = arr as (Array) + hilogAni.info(domain, tag, format, arr) + } + + export function warn(domain: number, tag: string, format: string, + ...args: (int | boolean | number | string | bigint | undefined)[]): void { + let arr: Array = {} + for (let i = 0; i < args.length; i++) { + arr.push(args[i]) + } + const args_casted = arr as (Array) + hilogAni.warn(domain, tag, format, arr) + } + + export function error(domain: number, tag: string, format: string, + ...args: (int | boolean | number | string | bigint | undefined)[]): void { + let arr: Array = {} + for (let i = 0; i < args.length; i++) { + arr.push(args[i]) + } + const args_casted = arr as (Array) + hilogAni.error(domain, tag, format, arr) + } + + export function fatal(domain: number, tag: string, format: string, + ...args: (int | boolean | number | string | bigint | undefined)[]): void { + let arr: Array = {} + for (let i = 0; i < args.length; i++) { + arr.push(args[i]) + } + const args_casted = arr as (Array) + hilogAni.fatal(domain, tag, format, arr) + } + + export function isLoggable(domain: number, tag: string, level: LogLevel): boolean { + return hilogAni.isLoggable(domain, tag, level) + } +} diff --git a/interfaces/ets/ani/hilog/include/hilog_ani.h b/interfaces/ets/ani/hilog/include/hilog_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..d92fb1b433d918a3d34ba79dfd384b545c68c886 --- /dev/null +++ b/interfaces/ets/ani/hilog/include/hilog_ani.h @@ -0,0 +1,62 @@ +/* + * 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 HILOG_ANI_H +#define HILOG_ANI_H + +#include + +enum AniArgsType { + ANI_NULL = -1, + ANI_INT = 0, + ANI_BOOLEAN = 1, + ANI_NUMBER = 2, + ANI_STRING = 3, + ANI_BIGINT = 4, + ANI_UNDEFINED = 5, +}; + +using AniParam = struct { + AniArgsType type; + std::string val; +}; + +struct LogContentInfo { + uint32_t count = 0; + bool isPriv = true; +}; + +class HilogAni { +public: + static void Debug(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args); + static void Info(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args); + static void Warn(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args); + static void Error(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args); + static void Fatal(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args); + static ani_boolean IsLoggable(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_enum_item level); + +private: + static void HilogImpl(ani_env *env, ani_double domain, ani_string tag, ani_string format, ani_object args, + int level, bool isAppLog); + static void parseAniValue(ani_env *env, ani_ref element, std::vector ¶ms); +}; + +#endif //HILOG_ANI_H diff --git a/interfaces/ets/ani/hilog/src/hilog_ani.cpp b/interfaces/ets/ani/hilog/src/hilog_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..60c6f4e7bec46bb90ac3effff570baba25368fe1 --- /dev/null +++ b/interfaces/ets/ani/hilog/src/hilog_ani.cpp @@ -0,0 +1,480 @@ +/* + * 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 +#include +#include +#include +#include "hilog/log.h" +#include "hilog/log_c.h" +#include "hilog/log_cpp.h" +#include "hilog_common.h" +#include "properties.h" +#include "securec.h" + +#include "hilog_ani.h" + +using namespace OHOS::HiviewDFX; + +static const HiLogLabel LABEL = { LOG_CORE, 0xD002D00, "HILOG_ANI" }; +static constexpr int MIN_NUMBER = 0; +static constexpr int MAX_NUMBER = 97; +static constexpr int PUBLIC_LEN = 6; +static constexpr int PRIVATE_LEN = 7; +static constexpr int PROPERTY_POS = 2; +static const std::string PRIV_STR = ""; +static const std::string CLASS_NAME_HILOGANI = "L@ohos/hilog/hilogAni;"; +static const std::string CLASS_NAME_INT = "Lstd/core/Int;"; +static const std::string CLASS_NAME_BOOLEAN = "Lstd/core/Boolean;"; +static const std::string CLASS_NAME_DOUBLE = "Lstd/core/Double;"; +static const std::string CLASS_NAME_BIGINT = "Lescompat/BigInt;"; +static const std::string ENUM_NAME_LOGLEVEL = "L@ohos/hilog/hilog/#LogLevel;"; +static const std::string FUNC_NAME_UNBOXED = "unboxed"; +static const std::string FUNC_NAME_GETLONG = "getLong"; +static const std::string FUNC_NAME_OBJECT_REF = "$_get"; +static const std::string PROP_NAME_LENGTH = "length"; + +static ani_status EnumGetValueInt32(ani_env *env, ani_enum_item enumItem, int32_t &value) +{ + ani_int aniInt {}; + if (ANI_OK != env->EnumItem_GetValue_Int(enumItem, &aniInt)) { + ani_size aniInt = 0; + HiLog::Info(LABEL, "EnumItem_GetValue_Int failed %{public}d", env->EnumItem_GetIndex(enumItem, &aniInt)); + return ANI_ERROR; + } + value = static_cast(aniInt); + return ANI_OK; +} + +static std::string AniStringToStdString(ani_env *env, ani_string aniStr) +{ + ani_size strSize; + env->String_GetUTF8Size(aniStr, &strSize); + std::vector buffer(strSize + 1); + char* utf8Buffer = buffer.data(); + ani_size bytesWritten = 0; + env->String_GetUTF8(aniStr, utf8Buffer, strSize + 1, &bytesWritten); + utf8Buffer[bytesWritten] = '\0'; + std::string content = std::string(utf8Buffer); + return content; +} + +static bool isIntParam(ani_env *env, ani_object elementObj) +{ + ani_class intClass; + if (ANI_OK != env->FindClass(CLASS_NAME_INT.c_str(), &intClass)) { + HiLog::Info(LABEL, "FindClass failed %{public}s", CLASS_NAME_INT.c_str()); + return false; + } + ani_boolean isInt; + if (ANI_OK != env->Object_InstanceOf(elementObj, intClass, &isInt)) { + return false; + } + return static_cast(isInt); +} + +static bool isBooleanParam(ani_env *env, ani_object elementObj) +{ + ani_class booleanClass; + if (ANI_OK != env->FindClass(CLASS_NAME_BOOLEAN.c_str(), &booleanClass)) { + HiLog::Info(LABEL, "FindClass failed %{public}s", CLASS_NAME_BOOLEAN.c_str()); + return false; + } + ani_boolean isBoolean; + if (ANI_OK != env->Object_InstanceOf(elementObj, booleanClass, &isBoolean)) { + return false; + } + return static_cast(isBoolean); +} + +static bool isDoubleParam(ani_env *env, ani_object elementObj) +{ + ani_class doubleClass; + if (ANI_OK != env->FindClass(CLASS_NAME_DOUBLE.c_str(), &doubleClass)) { + HiLog::Info(LABEL, "FindClass failed %{public}s", CLASS_NAME_DOUBLE.c_str()); + return false; + } + ani_boolean isDouble; + if (ANI_OK != env->Object_InstanceOf(elementObj, doubleClass, &isDouble)) { + return false; + } + return static_cast(isDouble); +} + +static bool isStringParam(ani_env *env, ani_object elementObj) +{ + ani_class stringClass; + const char *className = "Lstd/core/String;"; + if (ANI_OK != env->FindClass(className, &stringClass)) { + HiLog::Info(LABEL, "FindClass failed %{public}s", className); + return false; + } + ani_boolean isString; + if (ANI_OK != env->Object_InstanceOf(elementObj, stringClass, &isString)) { + return false; + } + return static_cast(isString); +} + +static bool isBigIntParam(ani_env *env, ani_object elementObj) +{ + ani_class bigIntClass; + if (ANI_OK != env->FindClass(CLASS_NAME_BIGINT.c_str(), &bigIntClass)) { + HiLog::Info(LABEL, "FindClass failed %{public}s", CLASS_NAME_BIGINT.c_str()); + return false; + } + ani_boolean isBigInt; + if (ANI_OK != env->Object_InstanceOf(elementObj, bigIntClass, &isBigInt)) { + return false; + } + return static_cast(isBigInt); +} + +static void parseIntParam(ani_env *env, ani_object elementObj, std::vector& params) +{ + ani_class intClass; + if (ANI_OK != env->FindClass(CLASS_NAME_INT.c_str(), &intClass)) { + HiLog::Info(LABEL, "FindClass failed %{public}s", CLASS_NAME_INT.c_str()); + return; + } + ani_method unboxedMethod; + if (ANI_OK != env->Class_FindMethod(intClass, FUNC_NAME_UNBOXED.c_str(), ":I", &unboxedMethod)) { + HiLog::Info(LABEL, "Class_FindMethod failed %{public}s", FUNC_NAME_UNBOXED.c_str()); + return; + } + ani_int intVal; + if (ANI_OK != env->Object_CallMethod_Int(elementObj, unboxedMethod, &intVal)) { + HiLog::Info(LABEL, "Object_CallMethod_Int failed %{public}s", FUNC_NAME_UNBOXED.c_str()); + return; + } + AniParam res; + res.type = AniArgsType::ANI_INT; + res.val = std::to_string(static_cast(intVal)); + params.emplace_back(res); + return; +} + +static void parseBooleanParam(ani_env *env, ani_object elementObj, std::vector& params) +{ + ani_class booleanClass; + if (ANI_OK != env->FindClass(CLASS_NAME_BOOLEAN.c_str(), &booleanClass)) { + HiLog::Info(LABEL, "FindClass failed %{public}s", CLASS_NAME_BOOLEAN.c_str()); + return; + } + ani_method unboxedMethod; + if (ANI_OK != env->Class_FindMethod(booleanClass, FUNC_NAME_UNBOXED.c_str(), ":Z", &unboxedMethod)) { + HiLog::Info(LABEL, "Class_FindMethod failed %{public}s", FUNC_NAME_UNBOXED.c_str()); + return; + } + ani_boolean booleanVal; + if (ANI_OK != env->Object_CallMethod_Boolean(elementObj, unboxedMethod, &booleanVal)) { + HiLog::Info(LABEL, "Object_CallMethod_Boolean failed %{public}s", FUNC_NAME_UNBOXED.c_str()); + return; + } + AniParam res; + res.type = AniArgsType::ANI_BOOLEAN; + res.val = booleanVal ? "true" : "false"; + params.emplace_back(res); + return; +} + +static void parseDoubleParam(ani_env *env, ani_object elementObj, std::vector& params) +{ + ani_class doubleClass; + if (ANI_OK != env->FindClass(CLASS_NAME_DOUBLE.c_str(), &doubleClass)) { + HiLog::Info(LABEL, "FindClass failed %{public}s", CLASS_NAME_DOUBLE.c_str()); + return; + } + ani_method unboxedMethod; + if (ANI_OK != env->Class_FindMethod(doubleClass, FUNC_NAME_UNBOXED.c_str(), ":D", &unboxedMethod)) { + HiLog::Info(LABEL, "Class_FindMethod failed %{public}s", FUNC_NAME_UNBOXED.c_str()); + return; + } + ani_double doubleVal; + if (ANI_OK != env->Object_CallMethod_Double(elementObj, unboxedMethod, &doubleVal)) { + HiLog::Info(LABEL, "Object_CallMethod_Double failed %{public}s", FUNC_NAME_UNBOXED.c_str()); + return; + } + AniParam res; + res.type = AniArgsType::ANI_NUMBER; + res.val = std::to_string(static_cast(doubleVal)); + params.emplace_back(res); + return; +} + +static void parseStringParam(ani_env *env, ani_object elementObj, std::vector& params) +{ + AniParam res; + res.type = AniArgsType::ANI_STRING; + res.val = AniStringToStdString(env, static_cast(elementObj)); + params.emplace_back(res); + return; +} + +static void parseBigIntParam(ani_env *env, ani_object elementObj, std::vector& params) +{ + ani_class bigIntClass; + env->FindClass(CLASS_NAME_BIGINT.c_str(), &bigIntClass); + ani_method getLongMethod; + if (ANI_OK != env->Class_FindMethod(bigIntClass, FUNC_NAME_GETLONG.c_str(), ":J", &getLongMethod)) { + HiLog::Info(LABEL, "Class_FindMethod failed %{public}s", FUNC_NAME_GETLONG.c_str()); + return; + } + ani_long longnum; + if (ANI_OK != env->Object_CallMethod_Long(elementObj, getLongMethod, &longnum)) { + HiLog::Info(LABEL, "Object_CallMethod_Long failed %{public}s", FUNC_NAME_GETLONG.c_str()); + return; + } + AniParam res; + res.type = AniArgsType::ANI_BIGINT; + res.val = std::to_string(static_cast(longnum)); + params.emplace_back(res); + return; +} + +void HilogAni::parseAniValue(ani_env *env, ani_ref element, std::vector& params) +{ + ani_boolean isUndefined; + env->Reference_IsUndefined(element, &isUndefined); + if (isUndefined) { + AniParam res; + res.type = AniArgsType::ANI_UNDEFINED; + res.val = "undefined"; + params.emplace_back(res); + return; + } + + ani_object elementObj = static_cast(element); + if (isIntParam(env, elementObj)) { + parseIntParam(env, elementObj, params); + return; + } else if (isBooleanParam(env, elementObj)) { + parseBooleanParam(env, elementObj, params); + return; + } else if (isDoubleParam(env, elementObj)) { + parseDoubleParam(env, elementObj, params); + return; + } else if (isStringParam(env, elementObj)) { + parseStringParam(env, elementObj, params); + return; + } else if (isBigIntParam(env, elementObj)) { + parseBigIntParam(env, elementObj, params); + return; + } + return; +} + +static void HandleFormatFlags(const std::string& formatStr, uint32_t& pos, bool& showPriv) +{ + if ((pos + PUBLIC_LEN + PROPERTY_POS) < formatStr.size() && + formatStr.substr(pos + PROPERTY_POS, PUBLIC_LEN) == "public") { + pos += (PUBLIC_LEN + PROPERTY_POS); + showPriv = false; + } + if ((pos + PRIVATE_LEN + PROPERTY_POS) < formatStr.size() && + formatStr.substr(pos + PROPERTY_POS, PRIVATE_LEN) == "private") { + pos += (PRIVATE_LEN + PROPERTY_POS); + } + return; +} + +static uint32_t ProcessLogContent(const std::string& formatStr, LogContentInfo& info, uint32_t pos, + const std::vector& params, std::string& ret) +{ + if (pos + 1 >= formatStr.size()) { + return pos; + } + switch (formatStr[pos + 1]) { + case 'd': + case 'i': + if (params[info.count].type == AniArgsType::ANI_INT || + params[info.count].type == AniArgsType::ANI_NUMBER || + params[info.count].type == AniArgsType::ANI_BIGINT) { + ret += info.isPriv ? PRIV_STR : params[info.count].val; + } + info.count++; + ++pos; + break; + case 's': + if (params[info.count].type == AniArgsType::ANI_STRING || + params[info.count].type == AniArgsType::ANI_UNDEFINED || + params[info.count].type == AniArgsType::ANI_BOOLEAN) { + ret += info.isPriv ? PRIV_STR : params[info.count].val; + } + info.count++; + ++pos; + break; + case 'O': + case 'o': + ++info.count; + ++pos; + break; + case '%': + ret += formatStr[pos]; + ++pos; + break; + default: + ret += formatStr[pos]; + break; + } + return pos; +} + +static void ParseLogContent(std::string& formatStr, std::vector& params, std::string& logContent) +{ + std::string& ret = logContent; + if (params.empty()) { + ret += formatStr; + return; + } + auto size = params.size(); + auto len = formatStr.size(); + uint32_t pos = 0; + bool debug = true; +#if not (defined(__WINDOWS__) || defined(__MAC__) || defined(__LINUX__)) + debug = IsDebugOn(); +#endif + bool priv = (!debug) && IsPrivateSwitchOn(); + LogContentInfo info; + info.count = 0; + for (; pos < len; ++pos) { + bool showPriv = true; + if (info.count >= size) { + break; + } + if (formatStr[pos] != '%') { + ret += formatStr[pos]; + continue; + } + HandleFormatFlags(formatStr, pos, showPriv); + info.isPriv = priv && showPriv; + pos = ProcessLogContent(formatStr, info, pos, params, ret); + } + if (pos < len) { + ret += formatStr.substr(pos, len - pos); + } + return; +} + +void HilogAni::HilogImpl(ani_env *env, ani_double domain, ani_string tag, + ani_string format, ani_object args, int level, bool isAppLog) +{ + int32_t domainVal = static_cast(domain); + if (domainVal < static_cast(DOMAIN_APP_MIN) || (domainVal > static_cast(DOMAIN_APP_MAX))) { + return; + } + std::string tagString = AniStringToStdString(env, tag); + std::string fmtString = AniStringToStdString(env, format); + + ani_double length; + if (ANI_OK != env->Object_GetPropertyByName_Double(args, PROP_NAME_LENGTH.c_str(), &length)) { + HiLog::Info(LABEL, "Object_GetPropertyByName_Double failed %{public}s", PROP_NAME_LENGTH.c_str()); + return; + } + if (MIN_NUMBER > length || MAX_NUMBER < length) { + HiLog::Info(LABEL, "%{public}s", "Argc mismatch"); + return; + } + std::string logContent; + std::vector params; + for (int32_t i = 0; i < static_cast(length); i++) { + ani_ref element; + if (ANI_OK != env->Object_CallMethodByName_Ref(args, FUNC_NAME_OBJECT_REF.c_str(), + "I:Lstd/core/Object;", &element, static_cast(i))) { + HiLog::Info(LABEL, "Object_CallMethodByName_Ref failed %{public}s", FUNC_NAME_OBJECT_REF.c_str()); + return; + } + parseAniValue(env, element, params); + } + ParseLogContent(fmtString, params, logContent); + HiLogPrint((isAppLog ? LOG_APP : LOG_CORE), + static_cast(level), domainVal, tagString.c_str(), "%{public}s", logContent.c_str()); + return; +} + +void HilogAni::Debug(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_DEBUG, true); +} + +void HilogAni::Info(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_INFO, true); +} + +void HilogAni::Warn(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_WARN, true); +} + +void HilogAni::Error(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_ERROR, true); +} + +void HilogAni::Fatal(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_string format, ani_object args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_FATAL, true); +} + +ani_boolean HilogAni::IsLoggable(ani_env *env, ani_object object, ani_double domain, ani_string tag, + ani_enum_item level) +{ + int32_t domainVal = static_cast(domain); + if (domainVal < static_cast(DOMAIN_APP_MIN) || (domainVal > static_cast(DOMAIN_APP_MAX))) { + return static_cast(false); + } + int32_t levelVal; + std::string tagStr = AniStringToStdString(env, tag); + if (ANI_OK != EnumGetValueInt32(env, level, levelVal)) { + return static_cast(false); + } + bool res = HiLogIsLoggable(domainVal, tagStr.c_str(), static_cast(levelVal)); + return static_cast(res); +} + +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_OUT_OF_REF; + } + + ani_class cls {}; + if (ANI_OK != env->FindClass(CLASS_NAME_HILOGANI.c_str(), &cls)) { + return ANI_INVALID_ARGS; + } + + std::array methods = { + ani_native_function {"debug", nullptr, reinterpret_cast(HilogAni::Debug)}, + ani_native_function {"info", nullptr, reinterpret_cast(HilogAni::Info)}, + ani_native_function {"warn", nullptr, reinterpret_cast(HilogAni::Warn)}, + ani_native_function {"error", nullptr, reinterpret_cast(HilogAni::Error)}, + ani_native_function {"fatal", nullptr, reinterpret_cast(HilogAni::Fatal)}, + ani_native_function {"isLoggable", nullptr, reinterpret_cast(HilogAni::IsLoggable)}, + }; + + if (ANI_OK != env->Class_BindNativeMethods(cls, methods.data(), methods.size())) { + return ANI_INVALID_TYPE; + }; + + *result = ANI_VERSION_1; + return ANI_OK; +}