diff --git a/frameworks/ets/ani/ani_common/BUILD.gn b/frameworks/ets/ani/ani_common/BUILD.gn index dc861272ce..d5757184a4 100644 --- a/frameworks/ets/ani/ani_common/BUILD.gn +++ b/frameworks/ets/ani/ani_common/BUILD.gn @@ -61,6 +61,7 @@ ohos_shared_library("ani_common") { "src/ani_common_execute_param.cpp", "src/ani_common_execute_result.cpp", "src/ani_common_intent_info_filter.cpp", + "src/ani_common_json_util.cpp", "src/ani_common_start_options.cpp", "src/ani_common_query_entity_param.cpp", "src/ani_common_util.cpp", diff --git a/frameworks/ets/ani/ani_common/include/ani_common_json_util.h b/frameworks/ets/ani/ani_common/include/ani_common_json_util.h new file mode 100644 index 0000000000..670c041f72 --- /dev/null +++ b/frameworks/ets/ani/ani_common/include/ani_common_json_util.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2026 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 OHOS_ABILITY_RUNTIME_ANI_COMMON_JSON_UTIL_H +#define OHOS_ABILITY_RUNTIME_ANI_COMMON_JSON_UTIL_H + +#include "ani.h" +#include "nlohmann/json.hpp" + +namespace OHOS { +namespace AppExecFwk { +bool CreateEmptyAniRecord(ani_env *env, ani_object &recordObject); +bool CreateAniArrayFromJson(ani_env *env, const nlohmann::json &jsonArray, ani_object &arrayObject); +bool CreateAniRecordFromJson(ani_env *env, const nlohmann::json &jsonObject, ani_object &recordObject); +} // namespace AppExecFwk +} // namespace OHOS + +#endif // OHOS_ABILITY_RUNTIME_ANI_COMMON_JSON_UTIL_H diff --git a/frameworks/ets/ani/ani_common/include/ani_common_want.h b/frameworks/ets/ani/ani_common/include/ani_common_want.h index f8be049200..6ab9aa56dc 100644 --- a/frameworks/ets/ani/ani_common/include/ani_common_want.h +++ b/frameworks/ets/ani/ani_common/include/ani_common_want.h @@ -41,9 +41,6 @@ ani_object WrapElementNameInner(ani_env *env, ani_class elementNameObj, ani_obje const AppExecFwk::ElementName &elementNameParam); ani_object CreateAniWant(ani_env *env, const AAFwk::Want &want); -bool CreateArrayFromJson(ani_env *env, const nlohmann::json &jsonArray, ani_object &arrayObject); -bool CreateRecordObjectFromJson(ani_env *env, - const nlohmann::json &jsonObject, ani_object &recordObject); } // namespace AppExecFwk } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_ANI_COMMON_WANT_H diff --git a/frameworks/ets/ani/ani_common/src/ani_common_json_util.cpp b/frameworks/ets/ani/ani_common/src/ani_common_json_util.cpp new file mode 100644 index 0000000000..d97bdd166c --- /dev/null +++ b/frameworks/ets/ani/ani_common/src/ani_common_json_util.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2026 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_common_json_util.h" + +#include "ani_common_cache_mgr.h" +#include "ani_common_util.h" +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +constexpr const char *CLASSNAME_ARRAY = "std.core.Array"; +constexpr const char *RECORD_SET_NAME = + "X{C{std.core.Numeric}C{std.core.String}C{std.core.BaseEnum}}Y:"; + +bool SetRecordValue(ani_env *env, ani_object recordObject, ani_string key, ani_object value) +{ + ani_class recordCls = nullptr; + ani_method recordSetMethod = nullptr; + AniCommonMethodCacheKey recordSet = std::make_pair("$_set", RECORD_SET_NAME); + if (!AniCommonCacheMgr::GetCachedClassAndMethod(env, CLASSNAME_RECORD, recordSet, + recordCls, recordSetMethod)) { + TAG_LOGE(AAFwkTag::ANI, "failed to get cached class and method for record $_set"); + return false; + } + + ani_status status = env->Object_CallMethod_Void(recordObject, recordSetMethod, key, value); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Object_CallMethod_Void failed status: %{public}d", status); + return false; + } + return true; +} + +bool CreateAniValueFromJson(ani_env *env, const nlohmann::json &jsonValue, ani_object &aniValue) +{ + if (jsonValue.is_object()) { + return CreateAniRecordFromJson(env, jsonValue, aniValue); + } + if (jsonValue.is_array()) { + return CreateAniArrayFromJson(env, jsonValue, aniValue); + } + if (jsonValue.is_string()) { + aniValue = GetAniString(env, jsonValue.get()); + return aniValue != nullptr; + } + if (jsonValue.is_boolean()) { + aniValue = CreateBoolean(env, jsonValue.get()); + return aniValue != nullptr; + } + if (jsonValue.is_number()) { + aniValue = CreateDouble(env, jsonValue.get()); + return aniValue != nullptr; + } + if (jsonValue.is_null()) { + return true; + } + + TAG_LOGW(AAFwkTag::ANI, "unsupported json value type"); + return false; +} +} // namespace + +bool CreateEmptyAniRecord(ani_env *env, ani_object &recordObject) +{ + ani_class recordCls = nullptr; + ani_method recordCtorMethod = nullptr; + AniCommonMethodCacheKey recordCtor = std::make_pair("", ":"); + if (!AniCommonCacheMgr::GetCachedClassAndMethod(env, CLASSNAME_RECORD, recordCtor, + recordCls, recordCtorMethod)) { + TAG_LOGE(AAFwkTag::ANI, "failed to get cached class and method for record ctor"); + return false; + } + ani_status status = env->Object_New(recordCls, recordCtorMethod, &recordObject); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Object_New failed: %{public}d", status); + return false; + } + return true; +} + +bool CreateAniArrayFromJson(ani_env *env, const nlohmann::json &jsonArray, ani_object &arrayObject) +{ + if (!jsonArray.is_array()) { + TAG_LOGE(AAFwkTag::ANI, "json is not array"); + return false; + } + + ani_class arrayCls = nullptr; + ani_status status = env->FindClass(CLASSNAME_ARRAY, &arrayCls); + if (status != ANI_OK || arrayCls == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "failed to find array class, status: %{public}d", status); + return false; + } + + ani_method arrayCtor = nullptr; + status = env->Class_FindMethod(arrayCls, "", "i:", &arrayCtor); + if (status != ANI_OK || arrayCtor == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "failed to find array constructor, status: %{public}d", status); + return false; + } + + status = env->Object_New(arrayCls, arrayCtor, &arrayObject, jsonArray.size()); + if (status != ANI_OK || arrayObject == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "failed to create array object, status: %{public}d", status); + return false; + } + + ani_size index = 0; + for (const auto &item : jsonArray) { + ani_object elementValue = nullptr; + if (!CreateAniValueFromJson(env, item, elementValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create array element"); + index++; + continue; + } + if (elementValue != nullptr) { + status = env->Object_CallMethodByName_Void(arrayObject, "$_set", "iY:", index, elementValue); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "failed to set array element, status: %{public}d", status); + return false; + } + } + index++; + } + return true; +} + +bool CreateAniRecordFromJson(ani_env *env, const nlohmann::json &jsonObject, ani_object &recordObject) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null env"); + return false; + } + if (!jsonObject.is_object()) { + TAG_LOGE(AAFwkTag::ANI, "json is not object"); + return false; + } + if (!CreateEmptyAniRecord(env, recordObject)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create record object"); + return false; + } + + for (const auto &item : jsonObject.items()) { + const std::string &key = item.key(); + const nlohmann::json &value = item.value(); + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "failed to create key string: %{public}s", key.c_str()); + continue; + } + + ani_object aniValue = nullptr; + if (!CreateAniValueFromJson(env, value, aniValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create value for key: %{public}s", key.c_str()); + continue; + } + if (aniValue == nullptr) { + continue; + } + if (!SetRecordValue(env, recordObject, aniKey, aniValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to set record for key: %{public}s", key.c_str()); + return false; + } + } + return true; +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/frameworks/ets/ani/ani_common/src/ani_common_want.cpp b/frameworks/ets/ani/ani_common/src/ani_common_want.cpp index 54b0b78cb7..49cab6a80f 100644 --- a/frameworks/ets/ani/ani_common/src/ani_common_want.cpp +++ b/frameworks/ets/ani/ani_common/src/ani_common_want.cpp @@ -15,6 +15,7 @@ #include "ani_common_want.h" #include "ani_common_cache_mgr.h" +#include "ani_common_json_util.h" #include "ani_common_util.h" #include "remote_object_taihe_ani.h" #include "array_wrapper.h" @@ -1078,102 +1079,6 @@ bool InnerWrapWantParamsArray( } } -bool InnerCreateArrayRecordFromJson(ani_env *env, const nlohmann::json &jsonArray, ani_object &arrayObject) -{ - ani_size index = 0; - for (const auto &item : jsonArray) { - ani_object elementValue = nullptr; - - if (item.is_object()) { - if (!CreateRecordObjectFromJson(env, item, elementValue)) { - TAG_LOGE(AAFwkTag::ANI, "failed to create object element"); - continue; - } - } else if (item.is_array()) { - if (!CreateArrayFromJson(env, item, elementValue)) { - TAG_LOGE(AAFwkTag::ANI, "failed to create array element"); - continue; - } - } else if (item.is_string()) { - elementValue = GetAniString(env, item.get()); - } else if (item.is_boolean()) { - if (!InnerCreateBooleanObject(env, item.get(), elementValue)) { - TAG_LOGE(AAFwkTag::ANI, "failed to create boolean element"); - continue; - } - } else if (item.is_number()) { - if (!InnerCreateDoubleObject(env, item.get(), elementValue)) { - TAG_LOGE(AAFwkTag::ANI, "failed to create double element"); - continue; - } - } - - if (elementValue != nullptr) { - ani_status status = env->Object_CallMethodByName_Void(arrayObject, "$_set", - "iY:", index, elementValue); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::ANI, "failed to set array element, status: %{public}d", status); - return false; - } - } - index++; - } - return true; -} - -bool InnerFillRecordFromJson(ani_env *env, const nlohmann::json &jsonObject, ani_object &recordObject) -{ - for (const auto &item : jsonObject.items()) { - const std::string &key = item.key(); - const nlohmann::json &value = item.value(); - ani_string aniKey = GetAniString(env, key); - if (aniKey == nullptr) { - TAG_LOGE(AAFwkTag::ANI, "failed to create key string: %{public}s", key.c_str()); - continue; - } - - ani_object aniValue = nullptr; - if (value.is_object()) { - if (!CreateRecordObjectFromJson(env, value, aniValue)) { - TAG_LOGE(AAFwkTag::ANI, - "failed to create nested record object for key: %{public}s", key.c_str()); - continue; - } - } else if (value.is_string()) { - aniValue = GetAniString(env, value.get()); - } else if (value.is_boolean()) { - if (!InnerCreateBooleanObject(env, value.get(), aniValue)) { - TAG_LOGE(AAFwkTag::ANI, "failed to create boolean object for key: %{public}s", key.c_str()); - continue; - } - } else if (value.is_number()) { - if (!InnerCreateDoubleObject(env, value.get(), aniValue)) { - TAG_LOGE(AAFwkTag::ANI, "failed to create double object for key: %{public}s", key.c_str()); - continue; - } - } else if (value.is_array()) { - if (!CreateArrayFromJson(env, value, aniValue)) { - TAG_LOGE(AAFwkTag::ANI, - "failed to create array object for key: %{public}s", key.c_str()); - continue; - } - } else { - TAG_LOGW(AAFwkTag::ANI, "unsupported json type for key: %{public}s", key.c_str()); - continue; - } - - if (aniValue == nullptr) { - TAG_LOGE(AAFwkTag::ANI, "null value object for key: %{public}s", key.c_str()); - continue; - } - - if (!InnerSetRecord(env, recordObject, aniKey, aniValue)) { - TAG_LOGE(AAFwkTag::ANI, "failed to set record for key: %{public}s", key.c_str()); - return false; - } - } - return true; -} } ani_object WrapWant(ani_env *env, const AAFwk::Want &want) @@ -1270,55 +1175,6 @@ ani_ref WrapWantParamsFD(ani_env *env, const AAFwk::WantParams &wantParams) return WrapWantParams(env, fds); } -bool CreateArrayFromJson(ani_env *env, const nlohmann::json &jsonArray, ani_object &arrayObject) -{ - if (!jsonArray.is_array()) { - TAG_LOGE(AAFwkTag::ANI, "json is not array"); - return false; - } - - ani_class arrayCls = nullptr; - ani_status status = env->FindClass("std.core.Array", &arrayCls); - if (status != ANI_OK || arrayCls == nullptr) { - TAG_LOGE(AAFwkTag::ANI, "failed to find array class, status: %{public}d", status); - return false; - } - - ani_method arrayCtor = nullptr; - status = env->Class_FindMethod(arrayCls, "", "i:", &arrayCtor); - if (status != ANI_OK || arrayCtor == nullptr) { - TAG_LOGE(AAFwkTag::ANI, "failed to find array constructor, status: %{public}d", status); - return false; - } - - status = env->Object_New(arrayCls, arrayCtor, &arrayObject, jsonArray.size()); - if (status != ANI_OK || arrayObject == nullptr) { - TAG_LOGE(AAFwkTag::ANI, "failed to create array object, status: %{public}d", status); - return false; - } - - if (!InnerCreateArrayRecordFromJson(env, jsonArray, arrayObject)) { - TAG_LOGE(AAFwkTag::ANI, "failed to create array record object from json"); - return false; - } - - return true; -} - -bool CreateRecordObjectFromJson(ani_env *env, const nlohmann::json &jsonObject, ani_object &recordObject) -{ - if (env == nullptr) { - TAG_LOGE(AAFwkTag::INTENT, "null env"); - return false; - } - if (!InnerCreateRecordObject(env, recordObject)) { - TAG_LOGE(AAFwkTag::ANI, "failed to create record object"); - return false; - } - - return InnerFillRecordFromJson(env, jsonObject, recordObject); -} - ani_ref WrapWantParams(ani_env *env, const AAFwk::WantParams &wantParams) { if (env == nullptr) { diff --git a/frameworks/ets/ani/insight_intent/insight_intent_driver/include/ets_insight_intent_driver_utils.h b/frameworks/ets/ani/insight_intent/insight_intent_driver/include/ets_insight_intent_driver_utils.h index 65169a487d..02647c537e 100644 --- a/frameworks/ets/ani/insight_intent/insight_intent_driver/include/ets_insight_intent_driver_utils.h +++ b/frameworks/ets/ani/insight_intent/insight_intent_driver/include/ets_insight_intent_driver_utils.h @@ -21,6 +21,7 @@ #include "ets_runtime.h" #include "insight_intent_execute_result.h" #include "insight_intent_info_for_query.h" +#include "nlohmann/json.hpp" #include "want_params.h" #include "want_params_wrapper.h" @@ -45,7 +46,6 @@ ani_object CreateEtsConfigPutParams(ani_env *env, const std::vector ani_object CreateEtsConfigIntentInfo(ani_env *env, const InsightIntentInfoForQuery &info); ani_object CreateInsightIntentInfoParam(ani_env *env, const std::string ¶mStr); ani_object CreateInsightIntentInfoWithJson(ani_env *env, const nlohmann::json &jsonObject); -bool CreateEmptyRecordObject(ani_env *env, ani_object &recordObject); void SetInsightIntentInfo(ani_env *env, ani_object objValue, const InsightIntentInfoForQuery &info); } // namespace AbilityRuntime diff --git a/frameworks/ets/ani/insight_intent/insight_intent_driver/src/ets_insight_intent_driver_utils.cpp b/frameworks/ets/ani/insight_intent/insight_intent_driver/src/ets_insight_intent_driver_utils.cpp index ca8bb9bb08..33e4aa4941 100644 --- a/frameworks/ets/ani/insight_intent/insight_intent_driver/src/ets_insight_intent_driver_utils.cpp +++ b/frameworks/ets/ani/insight_intent/insight_intent_driver/src/ets_insight_intent_driver_utils.cpp @@ -18,9 +18,8 @@ #include #include "ability_state.h" -#include "ani_common_cache_mgr.h" +#include "ani_common_json_util.h" #include "ani_common_util.h" -#include "ani_common_want.h" #include "ani_enum_convert.h" #include "hilog_tag_wrapper.h" @@ -455,45 +454,38 @@ ani_object CreateEtsFormInfoForQuery(ani_env *env, const FormInfoForQuery &info) return objValue; } -bool CreateEmptyRecordObject(ani_env *env, ani_object &recordObject) -{ - ani_class recordCls = nullptr; - ani_method recordCtorMethod = nullptr; - AppExecFwk::AniCommonMethodCacheKey recordCtor = std::make_pair("", ":"); - if (!AppExecFwk::AniCommonCacheMgr::GetCachedClassAndMethod(env, "std.core.Record", recordCtor, - recordCls, recordCtorMethod)) { - return false; - } - ani_status status = env->Object_New(recordCls, recordCtorMethod, &recordObject); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::ANI, "Object_New failed: %{public}d", status); - return false; - } - return true; -} - ani_object CreateInsightIntentInfoParam(ani_env *env, const std::string ¶mStr) { ani_object recordObject; if (paramStr.empty()) { TAG_LOGE(AAFwkTag::INTENT, "paramStr empty"); - CreateEmptyRecordObject(env, recordObject); + AppExecFwk::CreateEmptyAniRecord(env, recordObject); return recordObject; } nlohmann::json jsonObject = nlohmann::json::parse(paramStr, nullptr, false); if (jsonObject.is_discarded()) { TAG_LOGE(AAFwkTag::INTENT, "Parse param str fail"); - CreateEmptyRecordObject(env, recordObject); + AppExecFwk::CreateEmptyAniRecord(env, recordObject); return recordObject; } - if (!AppExecFwk::CreateRecordObjectFromJson(env, jsonObject, recordObject)) { + if (!AppExecFwk::CreateAniRecordFromJson(env, jsonObject, recordObject)) { TAG_LOGE(AAFwkTag::INTENT, "failed to create record object from json"); return nullptr; } return recordObject; } +ani_object CreateInsightIntentInfoWithJson(ani_env *env, const nlohmann::json &jsonObject) +{ + ani_object recordObject = nullptr; + if (!AppExecFwk::CreateAniRecordFromJson(env, jsonObject, recordObject)) { + TAG_LOGE(AAFwkTag::INTENT, "failed to create InsightIntent record object from JSON"); + return nullptr; + } + return recordObject; +} + ani_object CreateEtsInsightIntentInfoForQueryArray(ani_env *env, const std::vector &infos) { ani_class arrayCls = nullptr; diff --git a/frameworks/js/napi/insight_intent/insight_intent_driver/BUILD.gn b/frameworks/js/napi/insight_intent/insight_intent_driver/BUILD.gn index 8e44c27a2d..38edb8f258 100644 --- a/frameworks/js/napi/insight_intent/insight_intent_driver/BUILD.gn +++ b/frameworks/js/napi/insight_intent/insight_intent_driver/BUILD.gn @@ -45,6 +45,7 @@ ohos_shared_library("insightintentdriver_napi") { "hilog:libhilog", "ipc:ipc_core", "ipc:ipc_napi", + "json:nlohmann_json_static", "napi:ace_napi", ] cflags_cc = [] diff --git a/frameworks/js/napi/insight_intent/insight_intent_driver/js_insight_intent_driver_utils.h b/frameworks/js/napi/insight_intent/insight_intent_driver/js_insight_intent_driver_utils.h index a7d83e7356..a72fc30498 100644 --- a/frameworks/js/napi/insight_intent/insight_intent_driver/js_insight_intent_driver_utils.h +++ b/frameworks/js/napi/insight_intent/insight_intent_driver/js_insight_intent_driver_utils.h @@ -19,6 +19,7 @@ #include "insight_intent_execute_result.h" #include "insight_intent_info_for_query.h" #include "native_engine/native_engine.h" +#include "nlohmann/json.hpp" namespace OHOS { namespace AbilityRuntime { diff --git a/services/abilitymgr/include/inner_mission_info.h b/services/abilitymgr/include/inner_mission_info.h index 99e8597a61..7b7eb2731b 100644 --- a/services/abilitymgr/include/inner_mission_info.h +++ b/services/abilitymgr/include/inner_mission_info.h @@ -19,6 +19,7 @@ #include #include "mission_info.h" +#include "nlohmann/json.hpp" namespace OHOS { namespace AAFwk { diff --git a/services/abilitymgr/include/insight_intent/extract_insight_intent_profile.h b/services/abilitymgr/include/insight_intent/extract_insight_intent_profile.h index efccb4ca3d..705857448c 100644 --- a/services/abilitymgr/include/insight_intent/extract_insight_intent_profile.h +++ b/services/abilitymgr/include/insight_intent/extract_insight_intent_profile.h @@ -20,7 +20,7 @@ #include #include "insight_intent_execute_param.h" - +#include "nlohmann/json.hpp" namespace OHOS { namespace AbilityRuntime { using ExecuteMode = AppExecFwk::ExecuteMode; diff --git a/services/abilitymgr/include/insight_intent/insight_intent_profile.h b/services/abilitymgr/include/insight_intent/insight_intent_profile.h index 717949f2fe..97cdb46103 100644 --- a/services/abilitymgr/include/insight_intent/insight_intent_profile.h +++ b/services/abilitymgr/include/insight_intent/insight_intent_profile.h @@ -20,6 +20,7 @@ #include #include "insight_intent_execute_param.h" +#include "nlohmann/json.hpp" namespace OHOS { namespace AbilityRuntime {