From d202c3589df0123898f29e86463b30b075058219 Mon Sep 17 00:00:00 2001 From: buzhenwang Date: Mon, 14 Jul 2025 19:31:50 +0800 Subject: [PATCH] add hilog ani 0702 Signed-off-by: buzhenwang --- interfaces/ets/ani/hilog/BUILD.gn | 6 +- interfaces/ets/ani/hilog/ets/@ohos.hilog.ets | 88 +--- interfaces/ets/ani/hilog/include/ani_util.h | 48 ++ .../include/{hilog_ani.h => hilog_ani_base.h} | 54 +-- interfaces/ets/ani/hilog/src/ani_util.cpp | 119 +++++ interfaces/ets/ani/hilog/src/hilog_ani.cpp | 459 +----------------- .../ets/ani/hilog/src/hilog_ani_base.cpp | 239 +++++++++ 7 files changed, 468 insertions(+), 545 deletions(-) create mode 100644 interfaces/ets/ani/hilog/include/ani_util.h rename interfaces/ets/ani/hilog/include/{hilog_ani.h => hilog_ani_base.h} (42%) create mode 100644 interfaces/ets/ani/hilog/src/ani_util.cpp create mode 100644 interfaces/ets/ani/hilog/src/hilog_ani_base.cpp diff --git a/interfaces/ets/ani/hilog/BUILD.gn b/interfaces/ets/ani/hilog/BUILD.gn index f9d188c..574ca10 100644 --- a/interfaces/ets/ani/hilog/BUILD.gn +++ b/interfaces/ets/ani/hilog/BUILD.gn @@ -17,7 +17,11 @@ import("//build/ohos.gni") ohos_shared_library("hilog_ani") { include_dirs = [ "./include" ] - sources = [ "./src/hilog_ani.cpp" ] + sources = [ + "./src/ani_util.cpp", + "./src/hilog_ani.cpp", + "./src/hilog_ani_base.cpp", + ] configs = [ "../../../../frameworks/libhilog:libhilog_config" ] sanitize = { diff --git a/interfaces/ets/ani/hilog/ets/@ohos.hilog.ets b/interfaces/ets/ani/hilog/ets/@ohos.hilog.ets index 4124145..eb237b6 100644 --- a/interfaces/ets/ani/hilog/ets/@ohos.hilog.ets +++ b/interfaces/ets/ani/hilog/ets/@ohos.hilog.ets @@ -13,81 +13,33 @@ * 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 native function debug(domain: number, tag: string, format: string, + ...args: (int|boolean|number|string|bigint|Object|undefined|null)[]): void; - 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 native function info(domain: number, tag: string, format: string, + ...args: (int|boolean|number|string|bigint|Object|undefined|null)[]): void; - 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 native function warn(domain: number, tag: string, format: string, + ...args: (int|boolean|number|string|bigint|Object|undefined|null)[]): void; - 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 native function error(domain: number, tag: string, format: string, + ...args: (int|boolean|number|string|bigint|Object|undefined|null)[]): void; - 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 native function fatal(domain: number, tag: string, format: string, + ...args: (int|boolean|number|string|bigint|Object|undefined|null)[]): void; - export function isLoggable(domain: number, tag: string, level: LogLevel): boolean { - return hilogAni.isLoggable(domain, tag, level) + export native function isLoggable(domain: number, tag: string, level: LogLevel): boolean; + + export native function setMinLogLevel(level: LogLevel): void; + + export enum LogLevel { + DEBUG = 3, + INFO = 4, + WARN = 5, + ERROR = 6, + FATAL = 7 } } diff --git a/interfaces/ets/ani/hilog/include/ani_util.h b/interfaces/ets/ani/hilog/include/ani_util.h new file mode 100644 index 0000000..d136c27 --- /dev/null +++ b/interfaces/ets/ani/hilog/include/ani_util.h @@ -0,0 +1,48 @@ +/* + * 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_UTIL_H +#define ANI_UTIL_H + +#include +#include + +namespace OHOS { +namespace HiviewDFX { +enum AniArgsType { + ANI_UNKNOWN = -1, + ANI_INT = 0, + ANI_BOOLEAN = 1, + ANI_NUMBER = 2, + ANI_STRING = 3, + ANI_BIGINT = 4, + ANI_OBJECT = 5, + ANI_UNDEFINED = 6, + ANI_NULL = 7, +}; + +class AniUtil { +public: + static bool IsRefUndefined(ani_env *env, ani_ref ref); + static bool IsRefNull(ani_env *env, ani_ref ref); + static AniArgsType AniArgGetType(ani_env *env, ani_object element); + static bool AniEnumToInt32(ani_env *env, ani_enum_item enumItem, int32_t &value); + static std::string AniStringToStdString(ani_env *env, ani_string aniStr); + static std::string AniArgToString(ani_env *env, ani_object arg); +}; +} // namespace HiviewDFX +} // namespace OHOS + +#endif //ANI_UTIL_H diff --git a/interfaces/ets/ani/hilog/include/hilog_ani.h b/interfaces/ets/ani/hilog/include/hilog_ani_base.h similarity index 42% rename from interfaces/ets/ani/hilog/include/hilog_ani.h rename to interfaces/ets/ani/hilog/include/hilog_ani_base.h index d92fb1b..89445c6 100644 --- a/interfaces/ets/ani/hilog/include/hilog_ani.h +++ b/interfaces/ets/ani/hilog/include/hilog_ani_base.h @@ -13,50 +13,40 @@ * limitations under the License. */ -#ifndef HILOG_ANI_H -#define HILOG_ANI_H +#ifndef HILOG_ANI_BASE_H +#define HILOG_ANI_BASE_H #include +#include "ani_util.h" -enum AniArgsType { - ANI_NULL = -1, - ANI_INT = 0, - ANI_BOOLEAN = 1, - ANI_NUMBER = 2, - ANI_STRING = 3, - ANI_BIGINT = 4, - ANI_UNDEFINED = 5, -}; - +namespace OHOS { +namespace HiviewDFX { using AniParam = struct { AniArgsType type; std::string val; }; -struct LogContentInfo { - uint32_t count = 0; - bool isPriv = true; -}; +typedef struct { + uint32_t pos; + uint32_t count; +} LogContentPosition; -class HilogAni { +class HilogAniBase { 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); + static void Debug(ani_env *env, ani_double domain, ani_string tag, ani_string format, ani_array args); + static void HilogImpl(ani_env *env, ani_double domain, ani_string tag, ani_string format, ani_array args, + int level, bool isAppLog); + static void Info(ani_env *env, ani_double domain, ani_string tag, ani_string format, ani_array args); + static void Warn(ani_env *env, ani_double domain, ani_string tag, ani_string format, ani_array args); + static void Error(ani_env *env, ani_double domain, ani_string tag, ani_string format, ani_array args); + static void Fatal(ani_env *env, ani_double domain, ani_string tag, ani_string format, ani_array args); + static ani_boolean IsLoggable(ani_env *env, ani_double domain, ani_string tag, ani_enum_item level); + static void SetMinLogLevel(ani_env *env, 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); }; +} // namespace HiviewDFX +} // namespace OHOS -#endif //HILOG_ANI_H +#endif //HILOG_ANI_BASE_H diff --git a/interfaces/ets/ani/hilog/src/ani_util.cpp b/interfaces/ets/ani/hilog/src/ani_util.cpp new file mode 100644 index 0000000..2d86a83 --- /dev/null +++ b/interfaces/ets/ani/hilog/src/ani_util.cpp @@ -0,0 +1,119 @@ +/* + * 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 "hilog/log.h" +#include "hilog/log_c.h" +#include "hilog/log_cpp.h" +#include "hilog_common.h" +#include "properties.h" +#include "securec.h" + +#include "ani_util.h" +namespace OHOS { +namespace HiviewDFX { +const HiLogLabel LABEL = { LOG_CORE, 0xD002D00, "HILOG_ANI_UTIL" }; +constexpr char CLASS_NAME_INT[] = "std.core.Int"; +constexpr char CLASS_NAME_BOOLEAN[] = "std.core.Boolean"; +constexpr char CLASS_NAME_DOUBLE[] = "std.core.Double"; +constexpr char CLASS_NAME_STRING[] = "std.core.String"; +constexpr char CLASS_NAME_BIGINT[] = "escompat.BigInt"; +constexpr char CLASS_NAME_OBJECT[] = "std.core.Object"; +constexpr char FUNCTION_TOSTRING[] = "toString"; +constexpr char MANGLING_TOSTRING[] = ":C{std.core.String}"; +const std::pair OBJECT_TYPE[] = { + {CLASS_NAME_INT, AniArgsType::ANI_INT}, + {CLASS_NAME_BOOLEAN, AniArgsType::ANI_BOOLEAN}, + {CLASS_NAME_DOUBLE, AniArgsType::ANI_NUMBER}, + {CLASS_NAME_STRING, AniArgsType::ANI_STRING}, + {CLASS_NAME_BIGINT, AniArgsType::ANI_BIGINT}, + {CLASS_NAME_OBJECT, AniArgsType::ANI_OBJECT}, +}; + +bool AniUtil::IsRefUndefined(ani_env *env, ani_ref ref) +{ + ani_boolean isUndefined = ANI_FALSE; + env->Reference_IsUndefined(ref, &isUndefined); + return isUndefined; +} + +bool AniUtil::IsRefNull(ani_env *env, ani_ref ref) +{ + ani_boolean isUull = ANI_FALSE; + env->Reference_IsNull(ref, &isUull); + return isUull; +} + +AniArgsType AniUtil::AniArgGetType(ani_env *env, ani_object element) +{ + if (IsRefUndefined(env, static_cast(element))) { + return AniArgsType::ANI_UNDEFINED; + } + + if (IsRefNull(env, static_cast(element))) { + return AniArgsType::ANI_NULL; + } + + for (const auto &objType : OBJECT_TYPE) { + ani_class cls {}; + if (ANI_OK != env->FindClass(objType.first, &cls)) { + continue; + } + ani_boolean isInstance = false; + if (ANI_OK != env->Object_InstanceOf(element, cls, &isInstance)) { + continue; + } + if (static_cast(isInstance)) { + return objType.second; + } + } + return AniArgsType::ANI_UNKNOWN; +} + +bool AniUtil::AniEnumToInt32(ani_env *env, ani_enum_item enumItem, int32_t &value) +{ + ani_int aniInt = 0; + if (ANI_OK != env->EnumItem_GetValue_Int(enumItem, &aniInt)) { + HiLog::Info(LABEL, "Get enum value failed."); + return false; + } + value = static_cast(aniInt); + return true; +} + +std::string AniUtil::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'; + return std::string(utf8Buffer); +} + +std::string AniUtil::AniArgToString(ani_env *env, ani_object arg) +{ + ani_ref argStrRef {}; + if (ANI_OK != env->Object_CallMethodByName_Ref(arg, FUNCTION_TOSTRING, MANGLING_TOSTRING, &argStrRef)) { + HiLog::Info(LABEL, "Call ets method toString() failed."); + return ""; + } + return AniStringToStdString(env, static_cast(argStrRef)); +} +} // namespace HiviewDFX +} // namespace OHOS diff --git a/interfaces/ets/ani/hilog/src/hilog_ani.cpp b/interfaces/ets/ani/hilog/src/hilog_ani.cpp index 60c6f4e..6bb1662 100644 --- a/interfaces/ets/ani/hilog/src/hilog_ani.cpp +++ b/interfaces/ets/ani/hilog/src/hilog_ani.cpp @@ -15,464 +15,35 @@ #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" +#include "hilog_ani_base.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); -} - +static const std::string NAMESPACE_NAME_HILOG = "@ohos.hilog.hilog"; 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; + return ANI_ERROR; } - ani_class cls {}; - if (ANI_OK != env->FindClass(CLASS_NAME_HILOGANI.c_str(), &cls)) { - return ANI_INVALID_ARGS; + ani_namespace ns {}; + if (ANI_OK != env->FindNamespace(NAMESPACE_NAME_HILOG.c_str(), &ns)) { + return ANI_ERROR; } 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)}, + ani_native_function {"debug", nullptr, reinterpret_cast(HilogAniBase::Debug)}, + ani_native_function {"info", nullptr, reinterpret_cast(HilogAniBase::Info)}, + ani_native_function {"warn", nullptr, reinterpret_cast(HilogAniBase::Warn)}, + ani_native_function {"error", nullptr, reinterpret_cast(HilogAniBase::Error)}, + ani_native_function {"fatal", nullptr, reinterpret_cast(HilogAniBase::Fatal)}, + ani_native_function {"isLoggable", nullptr, reinterpret_cast(HilogAniBase::IsLoggable)}, + ani_native_function {"setMinLogLevel", nullptr, reinterpret_cast(HilogAniBase::SetMinLogLevel)}, }; - if (ANI_OK != env->Class_BindNativeMethods(cls, methods.data(), methods.size())) { - return ANI_INVALID_TYPE; + if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) { + return ANI_ERROR; }; *result = ANI_VERSION_1; diff --git a/interfaces/ets/ani/hilog/src/hilog_ani_base.cpp b/interfaces/ets/ani/hilog/src/hilog_ani_base.cpp new file mode 100644 index 0000000..e473023 --- /dev/null +++ b/interfaces/ets/ani/hilog/src/hilog_ani_base.cpp @@ -0,0 +1,239 @@ +/* + * 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 "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_base.h" + +namespace OHOS { +namespace HiviewDFX { +const HiLogLabel LABEL = { LOG_CORE, 0xD002D00, "HILOG_ETS" }; +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 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 void ProcessLogContent(const std::string &formatStr, const std::vector ¶ms, bool isPriv, + LogContentPosition &contentPos, std::string &ret) +{ + if (contentPos.pos + 1 >= formatStr.size()) { + return; + } + switch (formatStr[contentPos.pos + 1]) { + case 'd': + case 'i': + if (params[contentPos.count].type == AniArgsType::ANI_INT || + params[contentPos.count].type == AniArgsType::ANI_NUMBER || + params[contentPos.count].type == AniArgsType::ANI_BIGINT) { + ret += isPriv ? PRIV_STR : params[contentPos.count].val; + } + contentPos.count++; + ++contentPos.pos; + break; + case 's': + if (params[contentPos.count].type == AniArgsType::ANI_STRING || + params[contentPos.count].type == AniArgsType::ANI_UNDEFINED || + params[contentPos.count].type == AniArgsType::ANI_BOOLEAN || + params[contentPos.count].type == AniArgsType::ANI_NULL) { + ret += isPriv ? PRIV_STR : params[contentPos.count].val; + } + contentPos.count++; + ++contentPos.pos; + break; + case 'O': + case 'o': + if (params[contentPos.count].type == AniArgsType::ANI_OBJECT) { + ret += isPriv ? PRIV_STR : params[contentPos.count].val; + } + contentPos.count++; + ++contentPos.pos; + break; + case '%': + ret += formatStr[contentPos.pos]; + ++contentPos.pos; + break; + default: + ret += formatStr[contentPos.pos]; + break; + } + return; +} + +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(); + LogContentPosition contentPos; + contentPos.pos = 0; + contentPos.count = 0; + bool debug = true; +#if not (defined(__WINDOWS__) || defined(__MAC__) || defined(__LINUX__)) + debug = IsDebugOn(); +#endif + bool priv = (!debug) && IsPrivateSwitchOn(); + for (; contentPos.pos < len; ++contentPos.pos) { + bool showPriv = true; + if (contentPos.count >= size) { + break; + } + if (formatStr[contentPos.pos] != '%') { + ret += formatStr[contentPos.pos]; + continue; + } + HandleFormatFlags(formatStr, contentPos.pos, showPriv); + bool isPriv = priv && showPriv; + ProcessLogContent(formatStr, params, isPriv, contentPos, ret); + } + if (contentPos.pos < len) { + ret += formatStr.substr(contentPos.pos, len - contentPos.pos); + } + return; +} + +void HilogAniBase::HilogImpl(ani_env *env, ani_double domain, ani_string tag, + ani_string format, ani_array args, int level, bool isAppLog) +{ + int32_t domainVal = static_cast(domain); + std::string tagString = AniUtil::AniStringToStdString(env, tag); + std::string fmtString = AniUtil::AniStringToStdString(env, format); + + ani_size length = 0; + if (ANI_OK != env->Array_GetLength(args, &length)) { + HiLog::Info(LABEL, "Get array length failed"); + return; + } + if (MIN_NUMBER > length || MAX_NUMBER < length) { + HiLog::Info(LABEL, "%{public}s", "Argc mismatch"); + return; + } + std::string logContent; + std::vector params; + for (ani_size i = 0; i < length; i++) { + ani_ref element; + if (ANI_OK != env->Array_Get(args, i, &element)) { + HiLog::Info(LABEL, "Get element at index %{public}zu from array failed", i); + 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 HilogAniBase::parseAniValue(ani_env *env, ani_ref element, std::vector& params) +{ + AniParam res; + AniArgsType type = AniUtil::AniArgGetType(env, static_cast(element)); + res.type = type; + if (type == AniArgsType::ANI_UNDEFINED) { + res.val = "undefined"; + } else if (type == AniArgsType::ANI_NULL) { + res.val = "null"; + } else if (type != AniArgsType::ANI_UNKNOWN) { + res.val = AniUtil::AniArgToString(env, static_cast(element)); + } else { + HiLog::Info(LABEL, "%{public}s", "Type mismatch"); + } + params.emplace_back(res); + return; +} + +void HilogAniBase::Debug(ani_env *env, ani_double domain, ani_string tag, + ani_string format, ani_array args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_DEBUG, true); +} + +void HilogAniBase::Info(ani_env *env, ani_double domain, ani_string tag, + ani_string format, ani_array args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_INFO, true); +} + +void HilogAniBase::Warn(ani_env *env, ani_double domain, ani_string tag, + ani_string format, ani_array args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_WARN, true); +} + +void HilogAniBase::Error(ani_env *env, ani_double domain, ani_string tag, + ani_string format, ani_array args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_ERROR, true); +} + +void HilogAniBase::Fatal(ani_env *env, ani_double domain, ani_string tag, + ani_string format, ani_array args) +{ + return HilogImpl(env, domain, tag, format, args, LOG_FATAL, true); +} + +ani_boolean HilogAniBase::IsLoggable(ani_env *env, 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 = AniUtil::AniStringToStdString(env, tag); + if (!AniUtil::AniEnumToInt32(env, level, levelVal)) { + return static_cast(false); + } + bool res = HiLogIsLoggable(domainVal, tagStr.c_str(), static_cast(levelVal)); + return static_cast(res); +} + +void HilogAniBase::SetMinLogLevel(ani_env *env, ani_enum_item level) +{ + int32_t levelVal = LOG_LEVEL_MIN; + if (!AniUtil::AniEnumToInt32(env, level, levelVal)) { + return; + } + HiLogSetAppMinLogLevel(static_cast(levelVal)); + return; +} +} // namespace HiviewDFX +} // namespace OHOS -- Gitee