* 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 "sts_common.h"
#include "ans_log_wrapper.h"
#include "ani_common_util.h"
#include "os_account_constants.h"
#include "os_account_info.h"
#include "os_account_manager.h"
namespace OHOS {
namespace NotificationSts {
constexpr const char* CLASSNAME_BOOLEAN = "std.core.Boolean";
constexpr const char* CLASSNAME_DOUBLE = "std.core.Double";
constexpr const char* CLASSNAME_INT = "std.core.Int";
constexpr const char* CLASSNAME_LONG = "std.core.Long";
ani_object GetNullObject(ani_env *env)
{
if (env == nullptr) {
ANS_LOGE("GetNullObject failed, env is nullptr");
return nullptr;
}
ani_ref nullRef;
ani_status status = env->GetNull(&nullRef);
if (status != ANI_OK) {
ANS_LOGE("GetNull failed, status: %{public}d", status);
return nullptr;
}
return static_cast<ani_object>(nullRef);
}
std::string GetResizeStr(std::string instr, int32_t length)
{
if (static_cast<int32_t>(instr.length()) <= length) {
return instr;
} else {
int32_t endPos = 0;
for (int32_t i = 0; i < static_cast<int32_t>(instr.size());) {
if ((instr[i] & 0x80) == 0) {
i += 1;
} else if ((instr[i] & 0xE0) == 0xC0) {
i += 2;
} else if ((instr[i] & 0xF0) == 0xE0) {
i += 3;
} else if ((instr[i] & 0xF8) == 0xF0) {
i += 4;
} else {
i += 1;
}
if (i > length) {
break;
}
endPos = i;
}
return instr.substr(0, endPos);
}
}
int32_t GetOsAccountLocalIdFromUid(const int32_t uid, int32_t &userId)
{
int32_t ret = AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId);
if (ret != ERR_OK) {
ANS_LOGE("Get userId failed, uid = <%{public}d>, code is %{public}d", uid, ret);
return ret;
}
ANS_LOGD("Get userId succ, uid = <%{public}d> userId = <%{public}d>", uid, userId);
return ret;
}
bool IsUndefine(ani_env *env, const ani_object &obj)
{
if (env == nullptr || obj == nullptr) {
ANS_LOGE("IsUndefine fail, has nullptr");
return true;
}
ani_boolean isUndefined;
if (env->Reference_IsUndefined(obj, &isUndefined) != ANI_OK) {
ANS_LOGE("Reference_IsUndefined faild");
return true;
}
return (isUndefined == ANI_TRUE) ? true : false;
}
ani_status GetAniStringByString(ani_env* env, const std::string str, ani_string& aniStr)
{
if (env == nullptr) {
ANS_LOGE("GetAniStringByString fail, env is nullptr");
return ANI_INVALID_ARGS;
}
ani_status status = env->String_NewUTF8(str.c_str(), str.size(), &aniStr);
if (status != ANI_OK) {
ANS_LOGE("String_NewUTF8 failed %{public}d", status);
return status;
}
return status;
}
ani_status GetStringByAniString(ani_env *env, ani_string str, std::string &res)
{
if (str == nullptr || env == nullptr) {
ANS_LOGE("GetStringByAniString fail, has nullptr");
return ANI_INVALID_ARGS;
}
res = "";
ani_size sz {};
ani_status status = ANI_ERROR;
if ((status = env->String_GetUTF8Size(str, &sz)) != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return status;
}
res.resize(sz + 1);
if ((status = env->String_GetUTF8SubString(str, 0, sz, res.data(), res.size(), &sz)) != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return status;
}
res.resize(sz);
return status;
}
bool GetStringArrayByAniObj(ani_env *env, const ani_object ani_obj, std::vector<std::string> &stdVString)
{
if (env == nullptr || ani_obj == nullptr) {
ANS_LOGE("GetStringArrayByAniObj fail, has nullptr");
return false;
}
ani_int length;
ani_status status = env->Object_GetPropertyByName_Int(ani_obj, "length", &length);
if (status != ANI_OK) {
ANS_LOGE("Object_GetPropertyByName_Int faild. status %{public}d", status);
return false;
}
for (int32_t i = 0; i < length; i++) {
ani_ref stringEntryRef;
status = env->Object_CallMethodByName_Ref(ani_obj, "$_get", "i:Y", &stringEntryRef, i);
if (status != ANI_OK) {
ANS_LOGE("Object_CallMethodByName_Ref faild. status : %{public}d", status);
return false;
}
std::string std_string;
if ((status = GetStringByAniString(env, static_cast<ani_string>(stringEntryRef), std_string)) != ANI_OK) {
ANS_LOGE("GetStringByAniString faild. status %{public}d", status);
return false;
}
stdVString.emplace_back(std_string);
}
return true;
}
ani_status GetPropertyString(ani_env *env, ani_object obj, const char *name,
ani_boolean &isUndefined, std::string &outStr)
{
if (env == nullptr || obj == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyString fail, has nullptr");
return ANI_INVALID_ARGS;
}
ANS_LOGD("GetPropertyString: %{public}s", name);
ani_status status = ANI_ERROR;
ani_ref strRef;
if ((status =env->Object_GetPropertyByName_Ref(obj, name, &strRef)) != ANI_OK) {
ANS_LOGE("Object_GetField_Ref bundle fail, status: %{public}d", status);
return status;
}
status = env->Reference_IsUndefined(strRef, &isUndefined);
if (status != ANI_OK) {
ANS_LOGE("Failed to check undefined for '%{public}s', status: %{public}d", name, status);
return status;
}
if (isUndefined == ANI_TRUE) {
ANS_LOGE("%{public}s is undefined", name);
return status;
}
if ((status = GetStringByAniString(env, reinterpret_cast<ani_string>(strRef), outStr)) != ANI_OK) {
ANS_LOGE("GetStdString failed");
return status;
}
return status;
}
ani_status GetPropertyBool(ani_env *env, ani_object obj, const char *name,
ani_boolean &isUndefined, bool &outvalue)
{
ANS_LOGD("GetPropertyBool start");
if (env == nullptr || obj == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyBool fail, has nullptr");
return ANI_INVALID_ARGS;
}
ANS_LOGD("GetPropertyBool: %{public}s", name);
ani_ref refObj = nullptr;
ani_status status = ANI_ERROR;
status = env->Object_GetPropertyByName_Ref(obj, name, &refObj);
if (ANI_OK != status) {
ANS_LOGE("Object_GetPropertyByName_Ref fail, status: %{public}d", status);
return status;
}
if ((status = env->Reference_IsUndefined(refObj, &isUndefined)) != ANI_OK) {
ANS_LOGE("Reference_IsUndefined failed, status : %{public}d", status);
return status;
}
if (isUndefined) {
ANS_LOGE("%{public}s is undefined", name);
return ANI_INVALID_ARGS;
}
ani_boolean result = ANI_FALSE;
if ((status = env->Object_CallMethodByName_Boolean(static_cast<ani_object>(refObj),
"toBoolean", ":z", &result)) != ANI_OK) {
ANS_LOGE("Object_CallMethodByName_Boolean failed, status : %{public}d", status);
return status;
}
outvalue = (result == ANI_TRUE);
return status;
}
ani_status GetPropertyDouble(ani_env *env, ani_object obj, const char *name,
ani_boolean &isUndefined, ani_double &outvalue)
{
if (env == nullptr || obj == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyDouble fail, has nullptr");
return ANI_INVALID_ARGS;
}
ANS_LOGD("GetPropertyDouble: %{public}s", name);
ani_status status = ANI_ERROR;
ani_ref refObj;
status = GetPropertyRef(env, obj, name, isUndefined, refObj);
if (status != ANI_OK || isUndefined == ANI_TRUE) {
ANS_LOGE("%{public}s is undefined", name);
return ANI_INVALID_ARGS;
}
if ((status = env->Object_CallMethodByName_Double(static_cast<ani_object>(refObj),
"toDouble", ":d", &outvalue)) != ANI_OK) {
ANS_LOGE("Object_CallMethodByName_Double failed, status : %{public}d", status);
return status;
}
ANS_LOGD("GetPropertyDouble sucess");
return status;
}
ani_status GetPropertyValueDouble(ani_env *env, ani_object param, const char *name, double &value)
{
if (env == nullptr || param == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyValueDouble fail, has nullptr");
return ANI_INVALID_ARGS;
}
ani_status status = ANI_ERROR;
ani_double res = value;
if ((status = env->Object_GetPropertyByName_Double(param, name, &res)) != ANI_OK) {
ANS_LOGE("Object_GetPropertyByName_Double failed, status : %{public}d", status);
return status;
}
value = static_cast<double>(res);
return status;
}
ani_status GetPropertyInt(ani_env *env, ani_object obj, const char *name,
ani_boolean &isUndefined, ani_int &outvalue)
{
if (env == nullptr || obj == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyInt fail, has nullptr");
return ANI_INVALID_ARGS;
}
ANS_LOGD("GetPropertyInt: %{public}s", name);
ani_status status = ANI_ERROR;
ani_ref refObj;
status = GetPropertyRef(env, obj, name, isUndefined, refObj);
if (status != ANI_OK || isUndefined == ANI_TRUE) {
ANS_LOGE("%{public}s is undefined", name);
return ANI_INVALID_ARGS;
}
if ((status = env->Object_CallMethodByName_Int(static_cast<ani_object>(refObj),
"toInt", ":i", &outvalue)) != ANI_OK) {
ANS_LOGE("Object_CallMethodByName_Int failed, status : %{public}d", status);
return status;
}
ANS_LOGD("GetPropertyInt sucess");
return status;
}
ani_status GetPropertyLong(ani_env *env, ani_object obj, const char *name,
ani_boolean &isUndefined, ani_long &outvalue)
{
if (env == nullptr || obj == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyLong fail, has nullptr");
return ANI_INVALID_ARGS;
}
ANS_LOGD("GetPropertyLong: %{public}s", name);
ani_status status = ANI_ERROR;
ani_ref refObj;
status = GetPropertyRef(env, obj, name, isUndefined, refObj);
if (status != ANI_OK || isUndefined == ANI_TRUE) {
ANS_LOGE("%{public}s is undefined", name);
return ANI_INVALID_ARGS;
}
if ((status = env->Object_CallMethodByName_Long(static_cast<ani_object>(refObj),
"toLong", ":l", &outvalue)) != ANI_OK) {
ANS_LOGE("Object_CallMethodByName_Long failed, status : %{public}d", status);
return status;
}
ANS_LOGD("GetPropertyLong sucess");
return status;
}
void GetPropertyRefValue(ani_env *env, ani_object obj, const char *name, ani_boolean &isUndefined, ani_ref &outRef)
{
if (env == nullptr || obj == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyRefValue fail, has nullptr");
return;
}
outRef = nullptr;
isUndefined = ANI_TRUE;
ani_status status = ANI_ERROR;
status = env->Object_GetPropertyByName_Ref(obj, name, &outRef);
if (status != ANI_OK) {
ANS_LOGE("Object_GetPropertyByName_Ref failed, status : %{public}d", status);
return;
}
if (outRef == nullptr) {
return;
}
env->Reference_IsUndefined(outRef, &isUndefined);
}
ani_status GetPropertyRef(ani_env *env, ani_object obj, const char *name, ani_boolean &isUndefined, ani_ref &outRef)
{
ANS_LOGD("GetPropertyRef call");
if (env == nullptr || obj == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyRef fail, has nullptr");
return ANI_INVALID_ARGS;
}
ANS_LOGD("GetPropertyRef: %{public}s", name);
ani_status status = env->Object_GetPropertyByName_Ref(obj, name, &outRef);
if (status != ANI_OK) {
ANS_LOGE("Failed to get property '%{public}s', status: %{public}d", name, status);
return status;
}
if (outRef == nullptr) {
ANS_LOGE("get Ref fialed, outRef is nullptr");
return ANI_ERROR;
}
status = env->Reference_IsUndefined(outRef, &isUndefined);
if (status != ANI_OK) {
ANS_LOGE("Failed to check undefined for '%{public}s', status: %{public}d", name, status);
}
ANS_LOGD("GetPropertyRef end");
return status;
}
ani_status GetPropertyStringArray(ani_env *env, ani_object param, const char *name,
std::vector<std::string> &res, const uint32_t maxLen)
{
if (env == nullptr || param == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyStringArray fail, has nullptr");
return ANI_INVALID_ARGS;
}
ANS_LOGD("GetPropertyStringArray: %{public}s", name);
ani_ref arrayObj = nullptr;
ani_status status;
ani_int length;
ani_boolean isUndefined = ANI_FALSE;
if ((status = GetPropertyRef(env, param, name, isUndefined, arrayObj)) != ANI_OK || isUndefined == ANI_TRUE) {
ANS_LOGE("GetPropertyRef fail, status = %{public}d, isUndefind = %{public}d", status, isUndefined);
return ANI_INVALID_ARGS;
}
status = env->Object_GetPropertyByName_Int(static_cast<ani_object>(arrayObj), "length", &length);
if (status != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return status;
}
if (maxLen > 0 && length > static_cast<ani_int>(maxLen)) {
length = static_cast<ani_int>(maxLen);
}
std::string str = "";
for (int32_t i = 0; i < length; i++) {
ani_ref stringEntryRef;
status = env->Object_CallMethodByName_Ref(static_cast<ani_object>(arrayObj),
"$_get", "i:Y", &stringEntryRef, i);
if (status != ANI_OK) {
ANS_LOGE("status : %{public}d, index: %{public}d", status, i);
return status;
}
status = GetStringByAniString(env, static_cast<ani_string>(stringEntryRef), str);
if (status != ANI_OK) {
ANS_LOGE("GetStdString failed, index: %{public}d", i);
return status;
}
res.push_back(str);
}
return status;
}
ani_status GetPropertyEnumItemArray(ani_env *env, ani_object param, const char *name,
ani_boolean &isUndefined, std::vector<ani_enum_item> &res)
{
if (env == nullptr || param == nullptr || name == nullptr) {
ANS_LOGE("GetPropertyEnumItemArray fail, has nullptr");
return ANI_INVALID_ARGS;
}
ANS_LOGD("GetPropertyEnumItemArray: %{public}s", name);
ani_ref arrayObj = nullptr;
ani_status status;
ani_int length;
if ((status = GetPropertyRef(env, param, name, isUndefined, arrayObj)) != ANI_OK) {
ANS_LOGE("GetPropertyRef fail, status = %{public}d, isUndefind = %{public}d", status, isUndefined);
return ANI_INVALID_ARGS;
}
if (isUndefined == ANI_TRUE) {
return ANI_OK;
}
status = env->Object_GetPropertyByName_Int(static_cast<ani_object>(arrayObj), "length", &length);
if (status != ANI_OK) {
ANS_LOGE("status: %{public}d", status);
return status;
}
for (int i = 0; i < static_cast<int>(length); i++) {
ani_ref enumItemRef;
status = env->Object_CallMethodByName_Ref(static_cast<ani_object>(arrayObj),
"$_get", "i:Y", &enumItemRef, (ani_int)i);
if (status != ANI_OK) {
ANS_LOGE("status: %{public}d, index: %{public}d", status, i);
return status;
}
res.push_back(static_cast<ani_enum_item>(enumItemRef));
}
return ANI_OK;
}
ani_status GetPropertyNumberArray(ani_env *env, ani_object param, const char *name,
ani_boolean &isUndefined, std::vector<int64_t> &res)
{
ANS_LOGD("GetPropertyNumberArray enter");
ani_ref arrayObj = nullptr;
ani_status status;
ani_int length;
if ((status = GetPropertyRef(env, param, name, isUndefined, arrayObj)) != ANI_OK || isUndefined == ANI_TRUE) {
return ANI_INVALID_ARGS;
}
status = env->Object_GetPropertyByName_Int(static_cast<ani_object>(arrayObj), "length", &length);
if (status != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return status;
}
for (int32_t i = 0; i < length; i++) {
ani_ref numEntryRef;
status = env->Object_CallMethodByName_Ref(static_cast<ani_object>(arrayObj),
"$_get", "i:Y", &numEntryRef, i);
if (status != ANI_OK) {
ANS_LOGE("status : %{public}d, index: %{public}d", status, i);
return status;
}
ani_double doubleValue = 0.0;
status = env->Object_CallMethodByName_Double(static_cast<ani_object>(numEntryRef), "toDouble",
":d", &doubleValue);
if (status != ANI_OK) {
ANS_LOGE("Object_CallMethodByName_Double uid fail, status: %{public}d", status);
return status;
}
res.push_back(static_cast<int64_t>(doubleValue));
}
ANS_LOGD("GetPropertyNumberArray leave");
return status;
}
ani_status GetPropertyLongArray(ani_env *env, ani_object param, const char *name,
ani_boolean &isUndefined, std::vector<int64_t> &res)
{
ANS_LOGD("GetPropertyLongArray enter");
ani_ref arrayObj = nullptr;
ani_status status;
ani_int length;
if ((status = GetPropertyRef(env, param, name, isUndefined, arrayObj)) != ANI_OK || isUndefined == ANI_TRUE) {
ANS_LOGE("GetPropertyRef fail. status : %{public}d", status);
return ANI_INVALID_ARGS;
}
status = env->Object_GetPropertyByName_Int(static_cast<ani_object>(arrayObj), "length", &length);
if (status != ANI_OK) {
ANS_LOGE("Object_GetPropertyByName_Int status : %{public}d", status);
return status;
}
for (int32_t i = 0; i < length; i++) {
ani_ref numEntryRef;
status = env->Object_CallMethodByName_Ref(static_cast<ani_object>(arrayObj),
"$_get", "i:Y", &numEntryRef, i);
if (status != ANI_OK) {
ANS_LOGE("Object_CallMethodByName_Ref status : %{public}d, index: %{public}d", status, i);
return status;
}
ani_long longValue = 0.0;
status = env->Object_CallMethodByName_Long(static_cast<ani_object>(numEntryRef), "toLong",
":l", &longValue);
if (status != ANI_OK) {
ANS_LOGE("Object_CallMethodByName_Long uid fail, status: %{public}d", status);
return status;
}
res.push_back(static_cast<int64_t>(longValue));
}
ANS_LOGD("GetPropertyLongArray leave");
return status;
}
ani_object GetAniStringArrayByVectorString(ani_env *env, std::vector<std::string> strs)
{
if (env == nullptr) {
ANS_LOGE("GetAniStringArrayByVectorString fail, env is nullptr");
return nullptr;
}
int length = strs.size();
ani_array arrayObj = newArrayClass(env, length);
if (arrayObj == nullptr) {
return nullptr;
}
ani_size i = 0;
for (auto &str : strs) {
ani_string aniStr;
if ((GetAniStringByString(env, str, aniStr) != ANI_OK) || aniStr == nullptr) {
ANS_LOGE("GetAniStringByString faild");
return nullptr;
}
ani_status status = env->Array_Set(arrayObj, i, aniStr);
if (status != ANI_OK) {
ANS_LOGE("Array_Set failed %{public}d", status);
return nullptr;
}
i++;
}
return arrayObj;
}
bool GetAniStringArrayByVectorStringV2(ani_env *env, std::vector<std::string> strs, ani_object& aniArray)
{
ANS_LOGD("GetAniStringArrayByVectorStringV2 call");
if (env == nullptr) {
ANS_LOGE("GetAniStringArrayByVectorStringV2 failed, has nullptr");
return false;
}
ani_class cls = nullptr;
ani_status status = env->FindClass("std.core.String", &cls);
if (status != ANI_OK) {
ANS_LOGE("FindClass failed. status : %{public}d", status);
return false;
}
ani_array array = nullptr;
size_t size = strs.size();
ani_object nullObj = GetNullObject(env);
status = env->Array_New(size, nullObj, &array);
if (status != ANI_OK) {
ANS_LOGE("Array_New failed. status : %{public}d", status);
return false;
}
int32_t index = 0;
for (auto& str : strs) {
ani_string aniStr;
if ((GetAniStringByString(env, str, aniStr) != ANI_OK) || aniStr == nullptr) {
ANS_LOGE("GetAniStringByString failed");
return false;
}
status = env->Array_Set(array, index, aniStr);
if (status != ANI_OK) {
ANS_LOGE("Array_Set Failed. index = %{public}d, status = %{public}d", index, status);
return false;
}
index++;
}
ANS_LOGD("GetAniStringArrayByVectorStringV2 end");
aniArray = array;
return true;
}
bool SetFieldString(ani_env *env, ani_class cls, ani_object &object,
const std::string fieldName, const std::string value)
{
if (env == nullptr || cls == nullptr || object == nullptr || fieldName.empty()) {
ANS_LOGE("SetFieldString fail, has nullptr or fieldName is empty");
return false;
}
ani_field field = nullptr;
ani_string string = nullptr;
ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
ANS_LOGD("SetFieldString fieldName : %{public}s", fieldName.c_str());
if (status != ANI_OK || field == nullptr) {
ANS_LOGE("SetFieldString status : %{public}d", status);
return false;
}
if (value.empty()) {
ani_ref nullRef = nullptr;
if ((status = env->GetNull(&nullRef)) != ANI_OK) {
ANS_LOGE("SetFieldString GetNull fail status : %{public}d", status);
return false;
}
if ((status = env->Object_SetField_Ref(object, field, nullRef)) != ANI_OK) {
ANS_LOGE("SetFieldString Object_SetField_Ref fail status : %{public}d", status);
return false;
}
return true;
}
if ((status = env->String_NewUTF8(value.c_str(), value.size(), &string)) != ANI_OK) {
ANS_LOGE("SetFieldString String_NewUTF8 fail status : %{public}d", status);
return false;
}
if ((status = env->Object_SetField_Ref(object, field, string)) != ANI_OK) {
ANS_LOGE("SetFieldString Object_SetField_Ref fail status : %{public}d", status);
return false;
}
return true;
}
bool SetFieldInt(ani_env *env, ani_class cls, ani_object &object,
const std::string fieldName, const int32_t value)
{
if (env == nullptr || cls == nullptr || object == nullptr || fieldName.empty()) {
ANS_LOGE("SetFieldInt fail. has nullptr or fieldName is empty");
return false;
}
ani_field field = nullptr;
ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
ANS_LOGD("SetFieldInt fieldName : %{public}s", fieldName.c_str());
if (status != ANI_OK || field == nullptr) {
ANS_LOGE("Class_FindField fail. status : %{public}d", status);
return false;
}
if ((status = env->Object_SetField_Int(object, field, static_cast<ani_int>(value))) != ANI_OK) {
ANS_LOGE("Object_SetField_Int fail. status : %{public}d", status);
return false;
}
return true;
}
bool SetFieldLong(ani_env *env, ani_class cls, ani_object &object,
const std::string fieldName, const int64_t value)
{
if (env == nullptr || cls == nullptr || object == nullptr || fieldName.empty()) {
ANS_LOGE("SetFieldLong fail. has nullptr or fieldName is empty");
return false;
}
ani_field field = nullptr;
ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
ANS_LOGD("SetFieldLong fieldName : %{public}s", fieldName.c_str());
if (status != ANI_OK || field == nullptr) {
ANS_LOGE("Class_FindField fail. status : %{public}d", status);
return false;
}
if ((status = env->Object_SetField_Long(object, field, static_cast<ani_long>(value))) != ANI_OK) {
ANS_LOGE("Object_SetField_Long fail. status : %{public}d", status);
return false;
}
return true;
}
bool SetOptionalFieldBoolean(ani_env *env, ani_class cls, ani_object &object,
const std::string fieldName, bool value)
{
if (env == nullptr || cls == nullptr || object == nullptr || fieldName.empty()) {
ANS_LOGE("SetOptionalFieldBoolean fail, has nullptr or fieldName is empty");
return false;
}
ani_field field = nullptr;
ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
if (status != ANI_OK || field == nullptr) {
ANS_LOGE("Class_FindField failed or null field, status=%{public}d, fieldName=%{public}s",
status, fieldName.c_str());
return false;
}
ani_object boolObj = CreateBoolean(env, BoolToAniBoolean(value));
if (boolObj == nullptr) {
return false;
}
status = env->Object_SetField_Boolean(object, field, static_cast<ani_boolean>(value));
if (status != ANI_OK) {
ANS_LOGE("Object_SetField_Boolean failed, status=%{public}d, fieldName=%{public}s",
status, fieldName.c_str());
return false;
}
return true;
}
bool SetOptionalFieldDouble(ani_env *env, ani_class cls, ani_object &object,
const std::string fieldName, double value)
{
if (env == nullptr || cls == nullptr || object == nullptr || fieldName.empty()) {
ANS_LOGE("SetOptionalFieldDouble fail, has nullptr or fieldName is empty");
return false;
}
ani_field field = nullptr;
ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
if (status != ANI_OK || field == nullptr) {
ANS_LOGE("Class_FindField failed or null field, status=%{public}d, fieldName=%{public}s",
status, fieldName.c_str());
return false;
}
ani_object doubleObj = CreateDouble(env, value);
if (doubleObj == nullptr) {
return false;
}
status = env->Object_SetField_Ref(object, field, doubleObj);
if (status != ANI_OK) {
ANS_LOGE("Object_SetField_Ref failed, status=%{public}d, fieldName=%{public}s",
status, fieldName.c_str());
return false;
}
return true;
}
ani_object CreateBoolean(ani_env *env, bool value)
{
ani_class persion_cls;
ani_status status = ANI_ERROR;
if ((status = env->FindClass(CLASSNAME_BOOLEAN, &persion_cls)) != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return nullptr;
}
ani_method personInfoCtor;
if ((status = env->Class_FindMethod(persion_cls, "<ctor>", "z:", &personInfoCtor)) != ANI_OK) {
ANS_LOGE("Class_FindMethod fail, status : %{public}d", status);
return nullptr;
}
ani_object personInfoObj;
if ((status = env->Object_New(persion_cls, personInfoCtor, &personInfoObj, value ? ANI_TRUE : ANI_FALSE))
!= ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return nullptr;
}
return personInfoObj;
}
ani_object CreateLong(ani_env *env, int64_t value)
{
if (env == nullptr) {
ANS_LOGE("CreateLong fail, env is nullptr");
return nullptr;
}
ani_class longCls;
ani_status status = ANI_ERROR;
if ((status = env->FindClass(CLASSNAME_LONG, &longCls)) != ANI_OK) {
ANS_LOGE("FindClass fail, status : %{public}d", status);
return nullptr;
}
ani_method longCtor;
if ((status = env->Class_FindMethod(longCls, "<ctor>", "l:", &longCtor)) != ANI_OK) {
ANS_LOGE("Class_FindMethod fail, status : %{public}d", status);
return nullptr;
}
ani_object longObj;
if ((status = env->Object_New(longCls, longCtor, &longObj, value)) != ANI_OK) {
ANS_LOGE("Object_New fail, status : %{public}d", status);
return nullptr;
}
return longObj;
}
ani_object CreateDouble(ani_env *env, double value)
{
if (env == nullptr) {
ANS_LOGE("CreateDouble fail, env is nullptr");
return nullptr;
}
ani_class doubleCls;
ani_status status = ANI_ERROR;
if ((status = env->FindClass(CLASSNAME_DOUBLE, &doubleCls)) != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return nullptr;
}
ani_method doubleCtor;
if ((status = env->Class_FindMethod(doubleCls, "<ctor>", "d:", &doubleCtor)) != ANI_OK) {
ANS_LOGE("Class_FindMethod fail, status : %{public}d", status);
return nullptr;
}
ani_object doubleObj;
if ((status = env->Object_New(doubleCls, doubleCtor, &doubleObj, static_cast<ani_double>(value))) != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return nullptr;
}
return doubleObj;
}
ani_array newArrayClass(ani_env *env, int length)
{
ANS_LOGD("newArrayClass call");
if (env == nullptr || length < 0) {
ANS_LOGE("newArrayClass fail, env is nullptr or length is less than zero");
return nullptr;
}
ani_class arrayCls = nullptr;
if (ANI_OK != env->FindClass("std.core.Array", &arrayCls)) {
ANS_LOGE("FindClass std.core.Array Failed");
return nullptr;
}
ani_method arrayCtor;
if (ANI_OK != env->Class_FindMethod(arrayCls, "<ctor>", "i:", &arrayCtor)) {
ANS_LOGE("Class_FindMethod <ctor> Failed");
return nullptr;
}
ani_object arrayObj = nullptr;
if (env->Object_New(arrayCls, arrayCtor, &arrayObj, length) != ANI_OK) {
ANS_LOGE("Object_New Array Faild");
return nullptr;
}
ANS_LOGD("newArrayClass end");
return static_cast<ani_array>(arrayObj);
}
ani_object ConvertArrayLongToAniObj(ani_env *env, const std::vector<std::int64_t> values)
{
if (env == nullptr) {
ANS_LOGE("ConvertArrayLongToAniObj fail, env is nullptr");
return nullptr;
}
ani_array arrayObj = newArrayClass(env, values.size());
if (arrayObj == nullptr) {
return nullptr;
}
ani_size i = 0;
for (auto value : values) {
ani_object longObj = CreateLong(env, value);
if (longObj == nullptr) {
ANS_LOGE("null intObj");
return nullptr;
}
ani_status status = env->Array_Set(arrayObj, i, longObj);
if (status != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return nullptr;
}
i++;
}
return arrayObj;
}
bool SetOptionalFieldArrayLong(ani_env *env, ani_class cls, ani_object &object, const std::string fieldName,
const std::vector<std::int64_t> values)
{
if (env == nullptr || cls == nullptr || object == nullptr || fieldName.empty()) {
ANS_LOGE("SetOptionalFieldArrayLong fail, has nullptr or fieldName is empty");
return false;
}
ani_field field = nullptr;
ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
if (status != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return false;
}
ani_object arrayObj = ConvertArrayLongToAniObj(env, values);
if (arrayObj == nullptr) {
ANS_LOGE("arrayObj is nullptr.");
return false;
}
status = env->Object_SetField_Ref(object, field, arrayObj);
if (status != ANI_OK) {
ANS_LOGE("status : %{public}d", status);
return false;
}
return true;
}
bool CreateClassObjByClassName(ani_env *env, const char *className, ani_class &cls, ani_object &outAniObj)
{
if (env == nullptr || className == nullptr) {
ANS_LOGE("CreateClassObjByClassName fail, has nullptr");
return false;
}
if (env->FindClass(className, &cls) != ANI_OK) {
ANS_LOGE("FindClass fail");
return false;
}
ani_method ctor;
if (env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor) != ANI_OK) {
ANS_LOGE("FindMethod fail");
return false;
}
outAniObj = {};
if (env->Object_New(cls, ctor, &outAniObj) != ANI_OK) {
ANS_LOGE("Object_New fail");
return false;
}
return true;
}
bool CreateDate(ani_env *env, int64_t time, ani_object &outObj)
{
if (env == nullptr) {
ANS_LOGE("CreateDate fail, env is nullptr");
return false;
}
ani_class cls;
ani_status status;
if (ANI_OK != (status = env->FindClass("std.core.Date", &cls))) {
ANS_LOGE("error. not find class name 'std.core.Date'. status %{public}d", status);
return false;
}
ani_method ctor;
if ((status = env->Class_FindMethod(cls, "<ctor>", ":", &ctor)) != ANI_OK) {
ANS_LOGE("error. not find method name '<ctor>'. status %{public}d", status);
return false;
}
if ((status = env->Object_New(cls, ctor, &outObj)) != ANI_OK) {
ANS_LOGE("Object_New faild. status %{public}d", status);
return false;
}
ani_long msObj = 0;
if ((status = env->Object_CallMethodByName_Long(outObj, "setTime", "l:l", &msObj, time))
!= ANI_OK) {
ANS_LOGE("Object_CallMethodByName_Long setDate faild. status %{public}d", status);
return false;
}
return true;
}
bool GetDateByObject(ani_env *env, ani_object timeObj, int64_t &time)
{
ANS_LOGD("GetDateByObject call");
if (env == nullptr || timeObj == nullptr) {
ANS_LOGE("GetDateByObject fail, env or timeObj is nullptr");
return false;
}
ani_status status;
ani_long timeMsObj = 0;
if ((status = env->Object_CallMethodByName_Long(timeObj, "getTime", ":l", &timeMsObj)) != ANI_OK) {
ANS_LOGD("Object_CallMethodByName_Long faild. status %{public}d", status);
return false;
}
time = static_cast<int64_t>(timeMsObj);
ANS_LOGD("GetDateByObject end");
return true;
}
ani_object CreateInt(ani_env *env, int32_t value)
{
ani_class cls;
ani_status status = ANI_ERROR;
if ((status = env->FindClass(CLASSNAME_INT, &cls)) != ANI_OK) {
ANS_LOGE("FindClass '%{public}s' faild. status %{public}d", CLASSNAME_INT, status);
return nullptr;
}
ani_method ctor;
if ((status = env->Class_FindMethod(cls, "<ctor>", "i:", &ctor)) != ANI_OK) {
ANS_LOGE("Class_FindMethod '%{public}s' faild. status %{public}d", CLASSNAME_INT, status);
return nullptr;
}
ani_object outObj;
if ((status = env->Object_New(cls, ctor, &outObj, value)) != ANI_OK) {
ANS_LOGE("Object_New '%{public}s' faild. status %{public}d", CLASSNAME_INT, status);
return nullptr;
}
return outObj;
}
bool SetPropertyOptionalByBoolean(ani_env *env, ani_object &object, const char *name, bool value)
{
ANS_LOGD("enter SetPropertyOptionalByBoolean");
if (env == nullptr || object == nullptr || name == nullptr) {
ANS_LOGE("The parameter is invalid.");
return false;
}
ani_ref boolObj = CreateBoolean(env, value);
if (boolObj == nullptr) {
ANS_LOGE("CreateBoolean faild");
return false;
}
return SetPropertyByRef(env, object, name, boolObj);
}
bool SetPropertyOptionalByDouble(ani_env *env, ani_object &object, const char *name, double value)
{
ANS_LOGD("enter SetPropertyOptionalByDouble");
if (env == nullptr || object == nullptr || name == nullptr) {
ANS_LOGE("The parameter is invalid.");
return false;
}
ani_ref doubleObj = CreateDouble(env, value);
if (doubleObj == nullptr) {
ANS_LOGE("CreateDouble faild");
return false;
}
return SetPropertyByRef(env, object, name, doubleObj);
}
bool SetPropertyValueDouble(ani_env *env, ani_object param, const char *name, double value)
{
ANS_LOGD("enter SetPropertyValueDouble");
if (env == nullptr || param == nullptr || name == nullptr) {
ANS_LOGE("SetPropertyValueDouble fail, has nullptr");
return false;
}
ani_status status = ANI_ERROR;
if ((status = env->Object_SetPropertyByName_Double(param, name, value)) != ANI_OK) {
ANS_LOGE("Object_SetPropertyByName_Double, status: %{public}d", status);
return false;
}
return true;
}
bool SetPropertyOptionalByLong(ani_env *env, ani_object &object, const char *name, int64_t value)
{
ANS_LOGD("enter SetPropertyOptionalByLong");
if (env == nullptr || object == nullptr || name == nullptr) {
ANS_LOGE("The parameter is invalid.");
return false;
}
ani_ref longObj = CreateLong(env, value);
if (longObj == nullptr) {
ANS_LOGE("CreateLong faild");
return false;
}
return SetPropertyByRef(env, object, name, longObj);
}
bool SetPropertyOptionalByString(ani_env *env, ani_object &object, const char *name, const std::string value)
{
ANS_LOGD("enter SetPropertyOptionalByString");
if (env == nullptr || object == nullptr || name == nullptr) {
ANS_LOGE("The parameter is invalid.");
return false;
}
ani_string stringObj;
ani_status status = ANI_OK;
if ((status = GetAniStringByString(env, value, stringObj)) != ANI_OK) {
ANS_LOGE("GetAniStringByString faild. status %{public}d", status);
return false;
}
if (stringObj == nullptr) {
ANS_LOGE("CreateString faild");
return false;
}
return SetPropertyByRef(env, object, name, static_cast<ani_ref>(stringObj));
}
bool SetPropertyOptionalByInt(ani_env *env, ani_object &object, const char *name, int32_t value)
{
ANS_LOGD("enter SetPropertyOptionalByInt");
if (env == nullptr || object == nullptr || name == nullptr) {
ANS_LOGE("The parameter is invalid.");
return false;
}
ani_ref IntObj = CreateInt(env, value);
if (IntObj == nullptr) {
ANS_LOGE("CreateInt faild");
return false;
}
return SetPropertyByRef(env, object, name, IntObj);
}
bool SetPropertyByRef(ani_env *env, ani_object &object, const char *name, ani_ref value)
{
ANS_LOGD("enter SetPropertyByRef");
ani_status status = ANI_OK;
if (env == nullptr || object == nullptr || name == nullptr || value == nullptr) {
ANS_LOGE("The parameter is invalid.");
return false;
}
if ((status = env->Object_SetPropertyByName_Ref(object, name, value)) != ANI_OK) {
ANS_LOGE("set '%{public}s' faild. status %{public}d", name, status);
return false;
}
return true;
}
void ParseRecord(ani_env *env, ani_object recordRef, std::map<std::string, ani_ref>& recordResult)
{
if (env == nullptr) {
return;
}
ani_ref keys {};
if (env->Object_CallMethodByName_Ref(recordRef, "keys",
":C{std.core.IterableIterator}", &keys) != ANI_OK) {
ANS_LOGE("call method keys() failed.");
return;
}
ani_boolean done = ANI_FALSE;
while (!done) {
ani_ref next {};
if (env->Object_CallMethodByName_Ref(static_cast<ani_object>(keys), "next", nullptr, &next) != ANI_OK) {
ANS_LOGE("call method next() failed.");
break;
}
if (env->Object_GetFieldByName_Boolean(static_cast<ani_object>(next), "done", &done) != ANI_OK) {
ANS_LOGE("get field done failed.");
break;
}
if (done) {
break;
}
ani_ref keyRef {};
if (env->Object_GetFieldByName_Ref(static_cast<ani_object>(next), "value", &keyRef) != ANI_OK) {
ANS_LOGE("get field value failed.");
break;
}
ani_ref valueRef {};
if (env->Object_CallMethodByName_Ref(static_cast<ani_object>(recordRef),
"$_get", nullptr, &valueRef, keyRef) != ANI_OK) {
ANS_LOGE("call method $_get failed.");
break;
}
std::string keyStr;
GetStringByAniString(env, static_cast<ani_string>(keyRef), keyStr);
recordResult[keyStr] = valueRef;
}
}
ani_object CreateAniUndefined(ani_env *env)
{
if (env == nullptr) {
ANS_LOGE("CreateAniUndefined failed, env is nullptr");
return nullptr;
}
ani_ref aniRef;
ani_status status = env->GetUndefined(&aniRef);
if (status != ANI_OK) {
ANS_LOGE("GetUndefined failed, status: %{public}d", status);
return nullptr;
}
return reinterpret_cast<ani_object>(aniRef);
}
ani_object CreateMapObject(ani_env *env, const std::string name, const char *signature)
{
ani_class cls = nullptr;
if (env->FindClass(name.c_str(), &cls) != ANI_OK) {
ANS_LOGE("Failed to found %{public}s", name.c_str());
return nullptr;
}
ani_method ctor;
if (env->Class_FindMethod(cls, "<ctor>", signature, &ctor) != ANI_OK) {
ANS_LOGE("Failed to get ctor %{public}s", name.c_str());
return nullptr;
}
ani_object obj = {};
ani_ref undefinedArgument;
if (ANI_OK != env->GetUndefined(&undefinedArgument)) {
ANS_LOGE("Failed to get undefined %{public}s", name.c_str());
return nullptr;
}
if (env->Object_New(cls, ctor, &obj, undefinedArgument) != ANI_OK) {
ANS_LOGE("Failed to create object %{public}s", name.c_str());
return nullptr;
}
return obj;
}
ani_status GetMapIterator(ani_env *env, ani_object &mapObj, const char *method, ani_ref *it)
{
ani_status status = env->Object_CallMethodByName_Ref(mapObj, method, nullptr, it);
if (status != ANI_OK) {
ANS_LOGD("Failed to get %{public}s iterator, status: %{public}d", method, status);
}
return status;
}
ani_status GetMapIteratorNext(ani_env *env, ani_ref &it, ani_ref *next)
{
ani_status status = env->Object_CallMethodByName_Ref(reinterpret_cast<ani_object>(it), "next", nullptr, next);
if (status != ANI_OK) {
ANS_LOGD("Failed to get next, status: %{public}d", status);
}
return status;
}
ani_status GetMapIteratorStringValue(ani_env *env, ani_ref &next, std::string &str)
{
ani_ref val;
ani_status status = env->Object_GetFieldByName_Ref(reinterpret_cast<ani_object>(next), "value", &val);
if (status != ANI_OK) {
ANS_LOGD("Failed to get value, status: %{public}d", status);
}
status = GetStringByAniString(env, reinterpret_cast<ani_string>(val), str);
if (status == ANI_OK && str.size() > STRUCTURED_TEXT_SIZE) {
str.resize(STRUCTURED_TEXT_SIZE);
ANS_LOGW("Structured text truncated to 512 bytes.");
}
return status;
}
ani_status GetMapByAniMap(ani_env *env, ani_object &mapObj,
std::vector<std::pair<std::string, std::string>> &out)
{
ani_status status = ANI_ERROR;
ani_ref keys;
ani_ref values;
bool done = false;
if (GetMapIterator(env, mapObj, "keys", &keys) != ANI_OK ||
GetMapIterator(env, mapObj, "values", &values) != ANI_OK) {
return ANI_ERROR;
}
while (!done) {
ani_ref nextKey;
ani_ref nextVal;
ani_boolean done;
if (GetMapIteratorNext(env, keys, &nextKey) != ANI_OK ||
GetMapIteratorNext(env, values, &nextVal) != ANI_OK) {
return ANI_ERROR;
}
if ((status = env->Object_GetFieldByName_Boolean(reinterpret_cast<ani_object>(nextKey), "done", &done))
!= ANI_OK) {
ANS_LOGD("Failed to check iterator done, status: %{public}d", status);
return ANI_ERROR;
}
if (done) {
break;
}
std::string keyStr;
std::string valStr;
if (GetMapIteratorStringValue(env, nextKey, keyStr) != ANI_OK||
GetMapIteratorStringValue(env, nextVal, valStr) != ANI_OK) {
return ANI_ERROR;
}
out.emplace_back(keyStr, valStr);
}
return ANI_OK;
}
}
}