diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index 959c8c508c103a3dd37cc8f5f6f1790df2d69873..4d831ee83fecff9d007861abf0a26655eaa9a786 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -33,6 +33,7 @@ group("ani_packages") { "${ability_runtime_path}/frameworks/ets/ani/insight_intent/insight_intent_driver:insight_intent_driver_ani_kit", "${ability_runtime_path}/frameworks/ets/ani/ui_extension_callback:ani_ui_extension_callback", "${ability_runtime_path}/frameworks/ets/ani/uri_permission_manager:uri_permission_manager_ani_kit", + "${ability_runtime_path}/frameworks/ets/ani/want:want_ani_kit", "${ability_runtime_path}/frameworks/ets/ani/wantagent:aniwantagent", "${ability_runtime_path}/frameworks/ets/ani/apprecovery:appRecovery_ani", ] diff --git a/frameworks/ets/ani/ani_common/BUILD.gn b/frameworks/ets/ani/ani_common/BUILD.gn index 0a6e36105193cd7af603b92a5a38680c4d2b04f7..aa4d97e986e2cfa66713c082d598e48c76d61e83 100644 --- a/frameworks/ets/ani/ani_common/BUILD.gn +++ b/frameworks/ets/ani/ani_common/BUILD.gn @@ -96,6 +96,7 @@ ohos_shared_library("ani_common") { "hilog:libhilog", "hitrace:hitrace_meter", "image_framework:image_ani", + "ipc:rpc_ani", "ipc:ipc_core", "ipc:ipc_napi", "ipc:rpc_ani", 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 0ef32751c5e89c9a02b764ce18f53b0a01d5c31c..13ffe3226aa4538a18762c57eeb17724a814597a 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_util.h" +#include "ani_remote_object.h" #include "array_wrapper.h" #include "bool_wrapper.h" #include "byte_wrapper.h" @@ -37,12 +38,15 @@ namespace OHOS { namespace AppExecFwk { using namespace OHOS::AbilityRuntime; namespace { -constexpr const char* ABILITY_WANT_CLASS_NAME = "L@ohos/app/ability/Want/Want;"; -constexpr const char* TOOL_CLASS_NAME = "L@ohos/app/ability/Want/RecordSerializeTool;"; -constexpr const char* INNER_CLASS_NAME = "Lability/abilityResult/AbilityResultInner;"; -constexpr const char* ELEMENTNAME_CLASS_NAME = "LbundleManager/ElementNameInner/ElementNameInner;"; +constexpr const char *ABILITY_WANT_CLASS_NAME = "L@ohos/app/ability/Want/Want;"; +constexpr const char *TOOL_CLASS_NAME = "L@ohos/app/ability/Want/RecordSerializeTool;"; +constexpr const char *INNER_CLASS_NAME = "Lability/abilityResult/AbilityResultInner;"; +constexpr const char *ELEMENTNAME_CLASS_NAME = "LbundleManager/ElementNameInner/ElementNameInner;"; +constexpr const char *RECORD_CLASS_NAME = "Lescompat/Record;"; +constexpr const char *RECORD_SET_NAME = + "X{C{std.core.Numeric}C{std.core.String}C{std.core.BaseEnum}}C{std.core.Object}:"; -bool InnerWrapWantParams(ani_env* env, ani_class wantCls, ani_object wantObject, const AAFwk::WantParams& wantParams) +bool InnerWrapWantParams(ani_env *env, ani_class wantCls, ani_object wantObject, const AAFwk::WantParams &wantParams) { ani_ref wantParamRef = WrapWantParams(env, wantParams); if (wantParamRef == nullptr) { @@ -52,7 +56,7 @@ bool InnerWrapWantParams(ani_env* env, ani_class wantCls, ani_object wantObject, return SetFieldRefByName(env, wantCls, wantObject, "parameters", wantParamRef); } -bool InnerUnwrapWantParams(ani_env* env, ani_object wantObject, AAFwk::WantParams& wantParams) +bool InnerUnwrapWantParams(ani_env *env, ani_object wantObject, AAFwk::WantParams &wantParams) { ani_ref wantParamRef = nullptr; if (!GetFieldRefByName(env, wantObject, "parameters", wantParamRef)) { @@ -61,6 +65,946 @@ bool InnerUnwrapWantParams(ani_env* env, ani_object wantObject, AAFwk::WantParam } return UnwrapWantParams(env, wantParamRef, wantParams); } + +bool InnerCreateRecordObject(ani_env *env, ani_object &recordObject) +{ + ani_class recordCls = nullptr; + ani_method recordCtorMethod = nullptr; + ani_status status = env->FindClass(RECORD_CLASS_NAME, &recordCls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed status: %{public}d", status); + return false; + } + status = env->Class_FindMethod(recordCls, "", ":V", &recordCtorMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Class_FindMethod constructor failed: %{public}d", status); + return false; + } + 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 InnerSetRecord(ani_env *env, ani_object recordObject, ani_string key, ani_object value) +{ + ani_class recordCls = nullptr; + ani_method recordSetMethod = nullptr; + ani_status status = env->FindClass(RECORD_CLASS_NAME, &recordCls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed status: %{public}d", status); + return false; + } + status = env->Class_FindMethod(recordCls, "$_set", RECORD_SET_NAME, &recordSetMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Class_FindMethod set failed: %{public}d", status); + return false; + } + + 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 InnerWrapWantParamsString( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IString *ao = AAFwk::IString::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + std::string natValue = AAFwk::String::Unbox(ao); + ani_string aniValue = GetAniString(env, natValue); + if (aniValue == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "value GetAniString failed"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerCreateBooleanObject(ani_env *env, ani_boolean value, ani_object &object) +{ + ani_class cls = nullptr; + ani_method ctorMethod = nullptr; + ani_status status = env->FindClass("Lstd/core/Boolean;", &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed status: %{public}d", status); + return false; + } + status = env->Class_FindMethod(cls, "", "Z:V", &ctorMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Class_FindMethod constructor failed: %{public}d", status); + return false; + } + status = env->Object_New(cls, ctorMethod, &object, value); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Object_New failed: %{public}d", status); + return false; + } + return true; +} + +bool InnerWrapWantParamsBool( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IBoolean *ao = AAFwk::IBoolean::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + ani_boolean natValue = AAFwk::Boolean::Unbox(ao); + ani_object aniValue = nullptr; + if (!InnerCreateBooleanObject(env, natValue, aniValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create object"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerCreateShortObject(ani_env *env, ani_short value, ani_object &object) +{ + ani_class cls = nullptr; + ani_method ctorMethod = nullptr; + ani_status status = env->FindClass("Lstd/core/Short;", &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed status: %{public}d", status); + return false; + } + status = env->Class_FindMethod(cls, "", "S:V", &ctorMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Class_FindMethod constructor failed: %{public}d", status); + return false; + } + status = env->Object_New(cls, ctorMethod, &object, value); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Object_New failed: %{public}d", status); + return false; + } + return true; +} + +bool InnerWrapWantParamsShort( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IShort *ao = AAFwk::IShort::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + ani_short natValue = AAFwk::Short::Unbox(ao); + ani_object aniValue = nullptr; + if (!InnerCreateShortObject(env, natValue, aniValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create object"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerCreateIntObject(ani_env *env, ani_int value, ani_object &object) +{ + ani_class cls = nullptr; + ani_method ctorMethod = nullptr; + ani_status status = env->FindClass("Lstd/core/Int;", &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed status: %{public}d", status); + return false; + } + status = env->Class_FindMethod(cls, "", "I:V", &ctorMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Class_FindMethod constructor failed: %{public}d", status); + return false; + } + status = env->Object_New(cls, ctorMethod, &object, value); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Object_New failed: %{public}d", status); + return false; + } + return true; +} + +bool InnerWrapWantParamsInt32( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IInteger *ao = AAFwk::IInteger::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + ani_int natValue = AAFwk::Integer::Unbox(ao); + ani_object aniValue = nullptr; + if (!InnerCreateIntObject(env, natValue, aniValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create object"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerCreateLongObject(ani_env *env, ani_long value, ani_object &object) +{ + ani_class cls = nullptr; + ani_method ctorMethod = nullptr; + ani_status status = env->FindClass("Lstd/core/Long;", &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed status: %{public}d", status); + return false; + } + status = env->Class_FindMethod(cls, "", "J:V", &ctorMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Class_FindMethod constructor failed: %{public}d", status); + return false; + } + status = env->Object_New(cls, ctorMethod, &object, value); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Object_New failed: %{public}d", status); + return false; + } + return true; +} + +bool InnerWrapWantParamsInt64( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::ILong *ao = AAFwk::ILong::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + ani_long natValue = AAFwk::Long::Unbox(ao); + ani_object aniValue = nullptr; + if (!InnerCreateLongObject(env, natValue, aniValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create object"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerCreateFloatObject(ani_env *env, ani_float value, ani_object &object) +{ + ani_class cls = nullptr; + ani_method ctorMethod = nullptr; + ani_status status = env->FindClass("Lstd/core/Float;", &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed status: %{public}d", status); + return false; + } + status = env->Class_FindMethod(cls, "", "F:V", &ctorMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Class_FindMethod constructor failed: %{public}d", status); + return false; + } + status = env->Object_New(cls, ctorMethod, &object, value); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Object_New failed: %{public}d", status); + return false; + } + return true; +} + +bool InnerWrapWantParamsFloat( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IFloat *ao = AAFwk::IFloat::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + ani_float natValue = AAFwk::Float::Unbox(ao); + ani_object aniValue = nullptr; + if (!InnerCreateFloatObject(env, natValue, aniValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create object"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerCreateDoubleObject(ani_env *env, ani_double value, ani_object &object) +{ + ani_class cls = nullptr; + ani_method ctorMethod = nullptr; + ani_status status = env->FindClass("Lstd/core/Double;", &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed status: %{public}d", status); + return false; + } + status = env->Class_FindMethod(cls, "", "D:V", &ctorMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Class_FindMethod constructor failed: %{public}d", status); + return false; + } + status = env->Object_New(cls, ctorMethod, &object, value); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Object_New failed: %{public}d", status); + return false; + } + return true; +} + +bool InnerWrapWantParamsDouble( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IDouble *ao = AAFwk::IDouble::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + ani_double natValue = AAFwk::Double::Unbox(ao); + ani_object aniValue = nullptr; + if (!InnerCreateDoubleObject(env, natValue, aniValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create object"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerWrapWantParamsChar( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IChar *ao = AAFwk::IChar::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + std::string natValue = static_cast(ao)->ToString(); + ani_string aniValue = GetAniString(env, natValue); + if (aniValue == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "value GetAniString failed"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerWrapWantParamsByte( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IByte *ao = AAFwk::IByte::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + ani_int natValue = AAFwk::Byte::Unbox(ao); + ani_object aniValue = nullptr; + if (!InnerCreateIntObject(env, natValue, aniValue)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create object"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerWrapWantParamsWantParams( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IWantParams *ao = AAFwk::IWantParams::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + AAFwk::WantParams natValue = AAFwk::WantParamWrapper::Unbox(ao); + ani_ref aniValue = WrapWantParams(env, natValue); + if (aniValue == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null aniValue"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, reinterpret_cast(aniValue)); +} + +bool InnerWrapWantParamsRemoteObject( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + AAFwk::IRemoteObjectWrap *ao = AAFwk::IRemoteObjectWrap::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + auto remoteObject = AAFwk::RemoteObjectWrap::UnBox(ao); + ani_object aniValue = ANI_ohos_rpc_CreateJsRemoteObject(env, remoteObject); + if (aniValue == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null aniValue"); + return false; + } + return InnerSetRecord(env, recordObject, aniKey, aniValue); +} + +bool InnerSetArrayString(ani_env *env, ani_object recordObject, ani_string aniKey, + const std::vector &natArray) +{ + ani_class stringCls = nullptr; + ani_status status = env->FindClass("Lstd/core/String;", &stringCls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed, status: %{public}d", status); + return false; + } + ani_ref undefinedRef = nullptr; + status = env->GetUndefined(&undefinedRef); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetUndefined failed, status: %{public}d", status); + return false; + } + ani_array_ref refArray = nullptr; + status = env->Array_New_Ref(stringCls, natArray.size(), undefinedRef, &refArray); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_New failed, status: %{public}d", status); + return false; + } + + for (size_t i = 0; i < natArray.size(); i++) { + ani_string aniValue = GetAniString(env, natArray[i]); + if (aniValue == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "value GetAniString failed"); + continue; + } + status = env->Array_Set_Ref(refArray, i, aniValue); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_Set_Ref failed, status: %{public}d", status); + } + } + + return InnerSetRecord(env, recordObject, aniKey, refArray); +} + +bool InnerWrapWantParamsArrayString(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::IString *iValue = AAFwk::IString::Query(iface); + if (iValue != nullptr) { + natArray.push_back(AAFwk::String::Unbox(iValue)); + } + } + } + return InnerSetArrayString(env, recordObject, aniKey, natArray); +} + +bool InnerWrapWantParamsArrayBool(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::IBoolean *iValue = AAFwk::IBoolean::Query(iface); + if (iValue != nullptr) { + natArray.push_back(AAFwk::Boolean::Unbox(iValue)); + } + } + } + + ani_array_boolean aniArray = nullptr; + ani_status status = env->Array_New_Boolean(natArray.size(), &aniArray); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_New failed, status: %{public}d", status); + return false; + } + + auto *aniArrayBuf = reinterpret_cast(natArray.data()); + status = env->Array_SetRegion_Boolean(aniArray, 0, natArray.size(), aniArrayBuf); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_SetRegion_Boolean failed, status: %{public}d", status); + return false; + } + + return InnerSetRecord(env, recordObject, aniKey, aniArray); +} + +bool InnerWrapWantParamsArrayShort(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::IShort *iValue = AAFwk::IShort::Query(iface); + if (iValue != nullptr) { + natArray.push_back(AAFwk::Short::Unbox(iValue)); + } + } + } + + ani_array_short aniArray = nullptr; + ani_status status = env->Array_New_Short(natArray.size(), &aniArray); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_New failed, status: %{public}d", status); + return false; + } + + auto *aniArrayBuf = reinterpret_cast(natArray.data()); + status = env->Array_SetRegion_Short(aniArray, 0, natArray.size(), aniArrayBuf); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_SetRegion failed, status: %{public}d", status); + return false; + } + + return InnerSetRecord(env, recordObject, aniKey, aniArray); +} + +bool InnerWrapWantParamsArrayInt32(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::IInteger *iValue = AAFwk::IInteger::Query(iface); + if (iValue != nullptr) { + natArray.push_back(AAFwk::Integer::Unbox(iValue)); + } + } + } + + ani_array_int aniArray = nullptr; + ani_status status = env->Array_New_Int(natArray.size(), &aniArray); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_New failed, status: %{public}d", status); + return false; + } + + auto *aniArrayBuf = reinterpret_cast(natArray.data()); + status = env->Array_SetRegion_Int(aniArray, 0, natArray.size(), aniArrayBuf); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_SetRegion failed, status: %{public}d", status); + return false; + } + + return InnerSetRecord(env, recordObject, aniKey, aniArray); +} + +bool InnerWrapWantParamsArrayInt64(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::ILong *iValue = AAFwk::ILong::Query(iface); + if (iValue != nullptr) { + natArray.push_back(AAFwk::Long::Unbox(iValue)); + } + } + } + + ani_array_long aniArray = nullptr; + ani_status status = env->Array_New_Long(natArray.size(), &aniArray); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_New failed, status: %{public}d", status); + return false; + } + + auto *aniArrayBuf = reinterpret_cast(natArray.data()); + status = env->Array_SetRegion_Long(aniArray, 0, natArray.size(), aniArrayBuf); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_SetRegion failed, status: %{public}d", status); + return false; + } + + return InnerSetRecord(env, recordObject, aniKey, aniArray); +} + +bool InnerWrapWantParamsArrayFloat(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::IFloat *iValue = AAFwk::IFloat::Query(iface); + if (iValue != nullptr) { + natArray.push_back(AAFwk::Float::Unbox(iValue)); + } + } + } + + ani_array_float aniArray = nullptr; + ani_status status = env->Array_New_Float(natArray.size(), &aniArray); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_New failed, status: %{public}d", status); + return false; + } + + auto *aniArrayBuf = reinterpret_cast(natArray.data()); + status = env->Array_SetRegion_Float(aniArray, 0, natArray.size(), aniArrayBuf); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_SetRegion failed, status: %{public}d", status); + return false; + } + + return InnerSetRecord(env, recordObject, aniKey, aniArray); +} + +bool InnerWrapWantParamsArrayByte(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::IByte *iValue = AAFwk::IByte::Query(iface); + if (iValue != nullptr) { + natArray.push_back(AAFwk::Byte::Unbox(iValue)); + } + } + } + + ani_array_byte aniArray = nullptr; + ani_status status = env->Array_New_Byte(natArray.size(), &aniArray); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_New failed, status: %{public}d", status); + return false; + } + + auto *aniArrayBuf = reinterpret_cast(natArray.data()); + status = env->Array_SetRegion_Byte(aniArray, 0, natArray.size(), aniArrayBuf); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_SetRegion failed, status: %{public}d", status); + return false; + } + + return InnerSetRecord(env, recordObject, aniKey, aniArray); +} + +bool InnerWrapWantParamsArrayChar(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::IChar *iValue = AAFwk::IChar::Query(iface); + if (iValue != nullptr) { + std::string str(static_cast(iValue)->ToString()); + natArray.push_back(str); + } + } + } + + return InnerSetArrayString(env, recordObject, aniKey, natArray); +} + +bool InnerWrapWantParamsArrayDouble(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::IDouble *iValue = AAFwk::IDouble::Query(iface); + if (iValue != nullptr) { + natArray.push_back(AAFwk::Double::Unbox(iValue)); + } + } + } + + ani_array_double aniArray = nullptr; + ani_status status = env->Array_New_Double(natArray.size(), &aniArray); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_New failed, status: %{public}d", status); + return false; + } + + auto *aniArrayBuf = reinterpret_cast(natArray.data()); + status = env->Array_SetRegion_Double(aniArray, 0, natArray.size(), aniArrayBuf); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_SetRegion failed, status: %{public}d", status); + return false; + } + + return InnerSetRecord(env, recordObject, aniKey, aniArray); +} + +bool InnerSetArrayObject(ani_env *env, ani_object recordObject, ani_string aniKey, + const std::vector &natArray) +{ + ani_class recordCls = nullptr; + ani_status status = env->FindClass(RECORD_CLASS_NAME, &recordCls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "FindClass failed, status: %{public}d", status); + return false; + } + ani_ref undefinedRef = nullptr; + status = env->GetUndefined(&undefinedRef); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetUndefined failed, status: %{public}d", status); + return false; + } + ani_array_ref refArray = nullptr; + status = env->Array_New_Ref(recordCls, natArray.size(), undefinedRef, &refArray); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_New failed, status: %{public}d", status); + return false; + } + + for (size_t i = 0; i < natArray.size(); i++) { + ani_ref aniValue = WrapWantParams(env, natArray[i]); + if (aniValue == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "value GetAniString failed"); + continue; + } + status = env->Array_Set_Ref(refArray, i, aniValue); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "Array_Set_Ref failed, status: %{public}d", status); + } + } + + return InnerSetRecord(env, recordObject, aniKey, refArray); +} + +bool InnerWrapWantParamsArrayWantParams(ani_env *env, ani_object recordObject, const std::string &key, + const sptr &ao) +{ + ani_string aniKey = GetAniString(env, key); + if (aniKey == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "key GetAniString failed"); + return false; + } + + long size = 0; + ErrCode code = ao->GetLength(size); + if (code != ERR_OK) { + TAG_LOGE(AAFwkTag::ANI, "GetLength failed, status: %{public}d", code); + return false; + } + + std::vector natArray; + for (long i = 0; i < size; i++) { + sptr iface = nullptr; + if (ao->Get(i, iface) == ERR_OK) { + AAFwk::IWantParams *iValue = AAFwk::IWantParams::Query(iface); + if (iValue != nullptr) { + natArray.push_back(AAFwk::WantParamWrapper::Unbox(iValue)); + } + } + } + + return InnerSetArrayObject(env, recordObject, aniKey, natArray); +} + +bool InnerWrapWantParamsArray( + ani_env *env, ani_object recordObject, const std::string &key, const sptr &value) +{ + AAFwk::IArray *ao = AAFwk::IArray::Query(value); + if (ao == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null value"); + return false; + } + sptr array(ao); + if (array == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null array"); + return false; + } + + if (AAFwk::Array::IsStringArray(ao)) { + return InnerWrapWantParamsArrayString(env, recordObject, key, array); + } else if (AAFwk::Array::IsBooleanArray(ao)) { + return InnerWrapWantParamsArrayBool(env, recordObject, key, array); + } else if (AAFwk::Array::IsShortArray(ao)) { + return InnerWrapWantParamsArrayShort(env, recordObject, key, array); + } else if (AAFwk::Array::IsIntegerArray(ao)) { + return InnerWrapWantParamsArrayInt32(env, recordObject, key, array); + } else if (AAFwk::Array::IsLongArray(ao)) { + return InnerWrapWantParamsArrayInt64(env, recordObject, key, array); + } else if (AAFwk::Array::IsFloatArray(ao)) { + return InnerWrapWantParamsArrayFloat(env, recordObject, key, array); + } else if (AAFwk::Array::IsByteArray(ao)) { + return InnerWrapWantParamsArrayByte(env, recordObject, key, array); + } else if (AAFwk::Array::IsCharArray(ao)) { + return InnerWrapWantParamsArrayChar(env, recordObject, key, array); + } else if (AAFwk::Array::IsDoubleArray(ao)) { + return InnerWrapWantParamsArrayDouble(env, recordObject, key, array); + } else if (AAFwk::Array::IsWantParamsArray(ao)) { + return InnerWrapWantParamsArrayWantParams(env, recordObject, key, array); + } else { + return false; + } +} } ani_object WrapWant(ani_env *env, const AAFwk::Want &want) @@ -116,39 +1060,45 @@ ani_ref WrapWantParams(ani_env *env, const AAFwk::WantParams &wantParams) TAG_LOGE(AAFwkTag::ANI, "null env"); return nullptr; } - ani_status status = ANI_ERROR; - ani_class cls = nullptr; - if ((status = env->FindClass(TOOL_CLASS_NAME, &cls)) != ANI_OK) { - TAG_LOGE(AAFwkTag::ANI, "FindClass RecordSerializeTool failed, status: %{public}d", status); - return nullptr; - } - if (cls == nullptr) { - TAG_LOGE(AAFwkTag::ANI, "RecordSerializeTool class null"); - return nullptr; - } - ani_static_method parseNoThrowMethod = nullptr; - status = env->Class_FindStaticMethod(cls, "parseNoThrow", nullptr, &parseNoThrowMethod); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::ANI, "failed to get parseNoThrow method, status: %{public}d", status); - return nullptr; - } - nlohmann::json wantParamsJson = wantParams; - std::string wantParamsString = wantParamsJson.dump(); - ani_string wantParamsAniString; - status = env->String_NewUTF8(wantParamsString.c_str(), wantParamsString.length(), &wantParamsAniString); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::ANI, "String_NewUTF8 wantParamsString failed, status: %{public}d", status); + ani_object wantParamsRecord = nullptr; + if (!InnerCreateRecordObject(env, wantParamsRecord)) { + TAG_LOGE(AAFwkTag::ANI, "failed to create record object"); return nullptr; } - ani_ref wantParamsRef = nullptr; - status = env->Class_CallStaticMethod_Ref(cls, parseNoThrowMethod, &wantParamsRef, wantParamsAniString); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::ANI, "failed to call parseNoThrow method, status: %{public}d", status); - return nullptr; + const std::map> ¶mList = wantParams.GetParams(); + for (const auto &[first, second] : paramList) { + if (second == nullptr) { + continue; + } + if (AAFwk::IString::Query(second) != nullptr) { + InnerWrapWantParamsString(env, wantParamsRecord, first, second); + } else if (AAFwk::IBoolean::Query(second) != nullptr) { + InnerWrapWantParamsBool(env, wantParamsRecord, first, second); + } else if (AAFwk::IShort::Query(second) != nullptr) { + InnerWrapWantParamsShort(env, wantParamsRecord, first, second); + } else if (AAFwk::IInteger::Query(second) != nullptr) { + InnerWrapWantParamsInt32(env, wantParamsRecord, first, second); + } else if (AAFwk::ILong::Query(second) != nullptr) { + InnerWrapWantParamsInt64(env, wantParamsRecord, first, second); + } else if (AAFwk::IFloat::Query(second) != nullptr) { + InnerWrapWantParamsFloat(env, wantParamsRecord, first, second); + } else if (AAFwk::IDouble::Query(second) != nullptr) { + InnerWrapWantParamsDouble(env, wantParamsRecord, first, second); + } else if (AAFwk::IChar::Query(second) != nullptr) { + InnerWrapWantParamsChar(env, wantParamsRecord, first, second); + } else if (AAFwk::IByte::Query(second) != nullptr) { + InnerWrapWantParamsByte(env, wantParamsRecord, first, second); + } else if (AAFwk::IArray::Query(second) != nullptr) { + InnerWrapWantParamsArray(env, wantParamsRecord, first, second); + } else if (AAFwk::IWantParams::Query(second) != nullptr) { + InnerWrapWantParamsWantParams(env, wantParamsRecord, first, second); + } else if (AAFwk::IRemoteObjectWrap::Query(second) != nullptr) { + InnerWrapWantParamsRemoteObject(env, wantParamsRecord, first, second); + } } - return wantParamsRef; + return wantParamsRecord; } bool InnerWrapWantParamsString( diff --git a/frameworks/ets/ani/app/ability_context/include/ets_ability_context_module.h b/frameworks/ets/ani/app/ability_context/include/ets_ability_context_module.h index 30a77115e8d9bdd4ae1085791693326891f3d9e6..46d7f78c5eb20d44f51ebabc60c40dce2dbd0ae5 100644 --- a/frameworks/ets/ani/app/ability_context/include/ets_ability_context_module.h +++ b/frameworks/ets/ani/app/ability_context/include/ets_ability_context_module.h @@ -17,8 +17,8 @@ #define OHOS_ABILITY_RUNTIME_ETS_ABILITY_CONTEXT_MODULE_H #include -#include "ani.h" #include "ability_context.h" +#include "ani.h" #include "native_engine/native_engine.h" namespace OHOS { diff --git a/frameworks/ets/ani/ui_ability/include/ets_ability_context.h b/frameworks/ets/ani/ui_ability/include/ets_ability_context.h index 87a53791b3b388f0a4be79617969d13b6d0181bf..d6c7277cabbeb45ad727ece03b273e07014efb6e 100644 --- a/frameworks/ets/ani/ui_ability/include/ets_ability_context.h +++ b/frameworks/ets/ani/ui_ability/include/ets_ability_context.h @@ -93,8 +93,6 @@ public: static void Clean(ani_env *env, ani_object object); static ani_object SetEtsAbilityContext(ani_env *env, std::shared_ptr context); static EtsAbilityContext *GetEtsAbilityContext(ani_env *env, ani_object aniObj); - static ani_object NativeTransferStatic(ani_env *env, ani_object aniObj, ani_object input); - static ani_object NativeTransferDynamic(ani_env *env, ani_object aniObj, ani_object input); static bool IsInstanceOf(ani_env *env, ani_object aniObj); private: diff --git a/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp b/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp index 918a323ca386caaaec26971ec2721f3da12ae497..a38ac8cfad3227380db960c8f6b94a43cbf0a869 100644 --- a/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp +++ b/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp @@ -1222,85 +1222,6 @@ void EtsAbilityContext::ConfigurationUpdated(ani_env *env, std::shared_ptr *>(unwrapResult)->lock(); - if (context == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null context"); - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; - } - auto abilityContext = Context::ConvertTo(context); - if (abilityContext == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext"); - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; - } - auto &bindingObj = abilityContext->GetBindingObject(); - if (bindingObj == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null bindingObj"); - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; - } - auto staticContext = bindingObj->Get(); - if (staticContext == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null staticContext"); - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; - } - return reinterpret_cast(*staticContext); -} - -ani_object EtsAbilityContext::NativeTransferDynamic(ani_env *env, ani_object, ani_object input) -{ - TAG_LOGD(AAFwkTag::UIABILITY, "transfer dynamic UIAbilityContext"); - if (!IsInstanceOf(env, input)) { - TAG_LOGE(AAFwkTag::UIABILITY, "not UIAbilityContext"); - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; - } - auto context = ContextUtil::GetBaseContext(env, input); - if (context == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null context"); - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; - } - auto abilityContext = Context::ConvertTo(context); - if (abilityContext == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext"); - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; - } - auto &bindingObj = abilityContext->GetBindingObject(); - if (bindingObj == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null bindingObj"); - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; - } - auto dynamicContext = bindingObj->Get(); - if (dynamicContext == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null dynamicContext"); - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; - } - // Not support yet - EtsErrorUtil::ThrowEtsTransferClassError(env); - return nullptr; -} - bool EtsAbilityContext::IsInstanceOf(ani_env *env, ani_object aniObj) { ani_class cls {}; diff --git a/frameworks/ets/ani/want/BUILD.gn b/frameworks/ets/ani/want/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..51e2f6360d178eac88ba8bcd6741aa56fecaa355 --- /dev/null +++ b/frameworks/ets/ani/want/BUILD.gn @@ -0,0 +1,57 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +ohos_shared_library("want_ani_kit") { + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + branch_protector_ret = "pac_ret" + + include_dirs = [ + "./include", + "${ability_runtime_services_path}/common/include", + ] + + sources = [ "src/ani_want_module.cpp" ] + + deps = [ + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + ] + + external_deps = [ + "ability_base:want", + "ability_base:base", + "c_utils:utils", + "hilog:libhilog", + "ipc:rpc_ani", + "runtime_core:ani", + ] + + cflags_cc = [] + if (os_dlp_part_enabled) { + cflags_cc += [ "-DWITH_DLP" ] + } + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "ability" + part_name = "ability_runtime" +} diff --git a/frameworks/ets/ani/want/include/ani_want_module.h b/frameworks/ets/ani/want/include/ani_want_module.h new file mode 100644 index 0000000000000000000000000000000000000000..ee520b433618d9f55f8223fe56ce66ea57bb8245 --- /dev/null +++ b/frameworks/ets/ani/want/include/ani_want_module.h @@ -0,0 +1,74 @@ +/* + * 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 OHOS_ABILITY_RUNTIME_ANI_WANT_MODULE_H +#define OHOS_ABILITY_RUNTIME_ANI_WANT_MODULE_H + +#include "ani.h" +#include "want_params.h" + +namespace OHOS::AppExecFwk { +class EtsWantParams { +public: + EtsWantParams() = default; + ~EtsWantParams() = default; + + static ani_long NativeCreate(ani_env *env, ani_object); + static void NativeDestroy(ani_env *env, ani_object, ani_long nativeWantParams); + static ani_boolean NativeSetStringParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_string value); + static ani_boolean NativeSetDoubleParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_double value); + static ani_boolean NativeSetIntParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_int value); + static ani_boolean NativeSetLongParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_long value); + static ani_boolean NativeSetBooleanParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_boolean value); + static ani_boolean NativeSetWantParams(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_long value); + + static ani_boolean NativeSetArrayStringParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_object value); + static ani_boolean NativeSetArrayDoubleParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_object value); + static ani_boolean NativeSetArrayIntParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_object value); + static ani_boolean NativeSetArrayLongParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_object value); + static ani_boolean NativeSetArrayBooleanParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_object value); + static ani_boolean NativeSetArrayWantParams(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_object value); + + static ani_boolean NativeSetRemoteObjectParam(ani_env *env, ani_object, ani_long nativeWantParams, + ani_string key, ani_object value); + +private: + static bool SetArrayString(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams& wantParams); + static bool SetArrayDouble(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams& wantParams); + static bool SetArrayInt(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams& wantParams); + static bool SetArrayLong(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams& wantParams); + static bool SetArrayBoolean(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams& wantParams); + static bool SetArrayWantParams(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams& wantParams); +}; +} // namespace OHOS::AppExecFwk +#endif // OHOS_ABILITY_RUNTIME_ANI_WANT_MODULE_H diff --git a/frameworks/ets/ani/want/src/ani_want_module.cpp b/frameworks/ets/ani/want/src/ani_want_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1726c10222da825b35185f5cdd78366598285259 --- /dev/null +++ b/frameworks/ets/ani/want/src/ani_want_module.cpp @@ -0,0 +1,763 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_want_module.h" + +#include "ani_common_util.h" +#include "ani_remote_object.h" +#include "array_wrapper.h" +#include "bool_wrapper.h" +#include "double_wrapper.h" +#include "hilog_tag_wrapper.h" +#include "int_wrapper.h" +#include "long_wrapper.h" +#include "remote_object_wrapper.h" +#include "string_wrapper.h" +#include "want_params.h" +#include "want_params_wrapper.h" + +namespace OHOS::AppExecFwk { +namespace { +constexpr const char *ETS_NATIVE_WANT_PARAMS_CLASS_NAME = "L@ohos/app/ability/Want/NativeWantParams;"; +constexpr const char *ETS_NATIVE_WANT_PARAMS_CLEANER_CLASS_NAME = "L@ohos/app/ability/Want/NativeWantParamsCleaner;"; +} // namespace + +ani_long EtsWantParams::NativeCreate(ani_env *env, ani_object) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return 0; + } + auto *params = new(std::nothrow) AAFwk::WantParams(); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null params"); + return 0; + } + + return reinterpret_cast(params); +} + +void EtsWantParams::NativeDestroy(ani_env *env, ani_object, ani_long nativeWantParams) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return; + } + + delete params; +} + +ani_boolean EtsWantParams::NativeSetStringParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_string value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + std::string valueString; + if (!GetStdString(env, value, valueString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + params->SetParam(keyString, AAFwk::String::Box(valueString)); + return true; +} + +ani_boolean EtsWantParams::NativeSetDoubleParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_double value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + params->SetParam(keyString, AAFwk::Double::Box(value)); + return true; +} + +ani_boolean EtsWantParams::NativeSetIntParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_int value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + params->SetParam(keyString, AAFwk::Integer::Box(value)); + return true; +} + +ani_boolean EtsWantParams::NativeSetLongParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_long value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + params->SetParam(keyString, AAFwk::Long::Box(value)); + return true; +} + +ani_boolean EtsWantParams::NativeSetBooleanParam(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_boolean value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + params->SetParam(keyString, AAFwk::Boolean::Box(value)); + return true; +} + +ani_boolean EtsWantParams::NativeSetWantParams(ani_env *env, ani_object, ani_long nativeWantParams, ani_string key, + ani_long value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + auto *valueWantParams = reinterpret_cast(value); + if (valueWantParams == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null valueWantParams"); + return false; + } + + params->SetParam(keyString, AAFwk::WantParamWrapper::Box(*valueWantParams)); + return true; +} + +bool EtsWantParams::SetArrayString(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams &wantParams) +{ + ani_boolean isUndefined = true; + ani_status status = env->Reference_IsUndefined(value, &isUndefined); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Reference_IsUndefined status: %{public}d", status); + return false; + } + if (isUndefined) { + TAG_LOGE(AAFwkTag::WANT, "value is undefined"); + return false; + } + + ani_double valLength = 0.0; + status = env->Object_GetPropertyByName_Double(value, "length", &valLength); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Object_GetPropertyByName_Double status: %{public}d", status); + return false; + } + int32_t length = static_cast(valLength); + sptr ao = sptr::MakeSptr(length, AAFwk::g_IID_IString); + + for (int i = 0; i < length; i++) { + ani_ref itemRef; + status = env->Object_CallMethodByName_Ref(value, "$_get", "I:Lstd/core/Object;", &itemRef, i); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "status: %{public}d, index: %{public}d", status, i); + return false; + } + + std::string item; + if (!GetStdString(env, reinterpret_cast(itemRef), item)) { + TAG_LOGE(AAFwkTag::WANT, "GetStdString failed, index: %{public}d", i); + return false; + } + ao->Set(i, AAFwk::String::Box(item)); + } + wantParams.SetParam(key, ao); + return true; +} + +ani_boolean EtsWantParams::NativeSetArrayStringParam(ani_env *env, ani_object, ani_long nativeWantParams, + ani_string key, ani_object value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + return SetArrayString(env, keyString, value, *params); +} + +bool EtsWantParams::SetArrayDouble(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams &wantParams) +{ + ani_boolean isUndefined = true; + ani_status status = env->Reference_IsUndefined(value, &isUndefined); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Reference_IsUndefined status: %{public}d", status); + return false; + } + if (isUndefined) { + TAG_LOGE(AAFwkTag::WANT, "value is undefined"); + return false; + } + + ani_double valLength = 0.0; + status = env->Object_GetPropertyByName_Double(value, "length", &valLength); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Object_GetPropertyByName_Double status: %{public}d", status); + return false; + } + int32_t length = static_cast(valLength); + + auto array = reinterpret_cast(value); + std::vector nativeArray(length); + status = env->Array_GetRegion_Double(array, 0, length, nativeArray.data()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Array_GetRegion_Double status: %{public}d", status); + return false; + } + + sptr ao = sptr::MakeSptr(length, AAFwk::g_IID_IDouble); + for (int i = 0; i < length; i++) { + ao->Set(i, AAFwk::Double::Box(nativeArray[i])); + } + wantParams.SetParam(key, ao); + return true; +} + +ani_boolean EtsWantParams::NativeSetArrayDoubleParam(ani_env *env, ani_object, ani_long nativeWantParams, + ani_string key, ani_object value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + return SetArrayDouble(env, keyString, value, *params); +} + +bool EtsWantParams::SetArrayInt(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams &wantParams) +{ + ani_boolean isUndefined = true; + ani_status status = env->Reference_IsUndefined(value, &isUndefined); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Reference_IsUndefined status: %{public}d", status); + return false; + } + if (isUndefined) { + TAG_LOGE(AAFwkTag::WANT, "value is undefined"); + return false; + } + + ani_double valLength = 0.0; + status = env->Object_GetPropertyByName_Double(value, "length", &valLength); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Object_GetPropertyByName_Double status: %{public}d", status); + return false; + } + int32_t length = static_cast(valLength); + + auto array = reinterpret_cast(value); + std::vector nativeArray(length); + status = env->Array_GetRegion_Int(array, 0, length, nativeArray.data()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Array_GetRegion_Int status: %{public}d", status); + return false; + } + + sptr ao = sptr::MakeSptr(length, AAFwk::g_IID_IInteger); + for (int i = 0; i < length; i++) { + ao->Set(i, AAFwk::Integer::Box(nativeArray[i])); + } + wantParams.SetParam(key, ao); + return true; +} + +ani_boolean EtsWantParams::NativeSetArrayIntParam(ani_env *env, ani_object, ani_long nativeWantParams, + ani_string key, ani_object value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + return SetArrayInt(env, keyString, value, *params); +} + +bool EtsWantParams::SetArrayLong(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams &wantParams) +{ + ani_boolean isUndefined = true; + ani_status status = env->Reference_IsUndefined(value, &isUndefined); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Reference_IsUndefined status: %{public}d", status); + return false; + } + if (isUndefined) { + TAG_LOGE(AAFwkTag::WANT, "value is undefined"); + return false; + } + + ani_double valLength = 0.0; + status = env->Object_GetPropertyByName_Double(value, "length", &valLength); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Object_GetPropertyByName_Double status: %{public}d", status); + return false; + } + int32_t length = static_cast(valLength); + + auto array = reinterpret_cast(value); + std::vector nativeArray(length); + status = env->Array_GetRegion_Long(array, 0, length, nativeArray.data()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Array_GetRegion_Long status: %{public}d", status); + return false; + } + + sptr ao = sptr::MakeSptr(length, AAFwk::g_IID_ILong); + for (int i = 0; i < length; i++) { + ao->Set(i, AAFwk::Long::Box(nativeArray[i])); + } + wantParams.SetParam(key, ao); + return true; +} + +ani_boolean EtsWantParams::NativeSetArrayLongParam(ani_env *env, ani_object, ani_long nativeWantParams, + ani_string key, ani_object value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + return SetArrayLong(env, keyString, value, *params); +} + +bool EtsWantParams::SetArrayBoolean(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams &wantParams) +{ + ani_boolean isUndefined = true; + ani_status status = env->Reference_IsUndefined(value, &isUndefined); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Reference_IsUndefined status: %{public}d", status); + return false; + } + if (isUndefined) { + TAG_LOGE(AAFwkTag::WANT, "value is undefined"); + return false; + } + + ani_double valLength = 0.0; + status = env->Object_GetPropertyByName_Double(value, "length", &valLength); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Object_GetPropertyByName_Double status: %{public}d", status); + return false; + } + int32_t length = static_cast(valLength); + + auto array = reinterpret_cast(value); + std::vector nativeArray(length); + status = env->Array_GetRegion_Boolean(array, 0, length, nativeArray.data()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Array_GetRegion_Boolean status: %{public}d", status); + return false; + } + + sptr ao = sptr::MakeSptr(length, AAFwk::g_IID_IBoolean); + for (int i = 0; i < length; i++) { + ao->Set(i, AAFwk::Boolean::Box(nativeArray[i])); + } + wantParams.SetParam(key, ao); + return true; +} + +ani_boolean EtsWantParams::NativeSetArrayBooleanParam(ani_env *env, ani_object, ani_long nativeWantParams, + ani_string key, ani_object value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + return SetArrayBoolean(env, keyString, value, *params); +} + +bool EtsWantParams::SetArrayWantParams(ani_env *env, const std::string &key, ani_object value, + AAFwk::WantParams &wantParams) +{ + ani_boolean isUndefined = true; + ani_status status = env->Reference_IsUndefined(value, &isUndefined); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Reference_IsUndefined status: %{public}d", status); + return false; + } + if (isUndefined) { + TAG_LOGE(AAFwkTag::WANT, "value is undefined"); + return false; + } + + ani_double valLength = 0.0; + status = env->Object_GetPropertyByName_Double(value, "length", &valLength); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Object_GetPropertyByName_Double status: %{public}d", status); + return false; + } + int32_t length = static_cast(valLength); + + auto array = reinterpret_cast(value); + std::vector nativeArray(length); + status = env->Array_GetRegion_Long(array, 0, length, nativeArray.data()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Array_GetRegion_Long status: %{public}d", status); + return false; + } + + sptr ao = sptr::MakeSptr(length, AAFwk::g_IID_IWantParams); + for (int i = 0; i < length; i++) { + auto *params = reinterpret_cast(nativeArray[i]); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + ao->Set(i, AAFwk::WantParamWrapper::Box(*params)); + } + wantParams.SetParam(key, ao); + return true; +} + +ani_boolean EtsWantParams::NativeSetArrayWantParams(ani_env *env, ani_object, ani_long nativeWantParams, + ani_string key, ani_object value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + return SetArrayWantParams(env, keyString, value, *params); +} + +ani_boolean EtsWantParams::NativeSetRemoteObjectParam(ani_env *env, ani_object, ani_long nativeWantParams, + ani_string key, ani_object value) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null env"); + return false; + } + + auto *params = reinterpret_cast(nativeWantParams); + if (params == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null nativeWantParams"); + return false; + } + + std::string keyString; + if (!GetStdString(env, key, keyString)) { + TAG_LOGE(AAFwkTag::WANT, "get key failed"); + return false; + } + + auto remoteObject = AniGetNativeRemoteObject(env, value); + if (remoteObject == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null remoteObject"); + return false; + } + params->SetParam(keyString, AAFwk::RemoteObjectWrap::Box(remoteObject)); + return true; +} + +ani_status BindNativeFunctions(ani_env *aniEnv) +{ + TAG_LOGD(AAFwkTag::WANT, "call"); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null ani env"); + return ANI_INVALID_ARGS; + } + + ani_class nativeWantParamsCls = nullptr; + auto status = aniEnv->FindClass(ETS_NATIVE_WANT_PARAMS_CLASS_NAME, &nativeWantParamsCls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "FindClass NativeWantParams failed status: %{public}d", status); + return status; + } + + std::array nativeFuncs = { + ani_native_function{ + "nativeCreate", ":J", + reinterpret_cast(EtsWantParams::NativeCreate) + }, + ani_native_function{ + "nativeSetStringParam", "JLstd/core/String;Lstd/core/String;:Z", + reinterpret_cast(EtsWantParams::NativeSetStringParam) + }, + ani_native_function{ + "nativeSetDoubleParam", "JLstd/core/String;D:Z", + reinterpret_cast(EtsWantParams::NativeSetDoubleParam) + }, + ani_native_function{ + "nativeSetIntParam", "JLstd/core/String;I:Z", + reinterpret_cast(EtsWantParams::NativeSetIntParam) + }, + ani_native_function{ + "nativeSetLongParam", "JLstd/core/String;J:Z", + reinterpret_cast(EtsWantParams::NativeSetLongParam) + }, + ani_native_function{ + "nativeSetBooleanParam", "JLstd/core/String;Z:Z", + reinterpret_cast(EtsWantParams::NativeSetBooleanParam) + }, + ani_native_function{ + "nativeSetWantParams", "JLstd/core/String;J:Z", + reinterpret_cast(EtsWantParams::NativeSetWantParams) + }, + ani_native_function{ + "nativeSetArrayStringParam", "JLstd/core/String;Lescompat/Array;:Z", + reinterpret_cast(EtsWantParams::NativeSetArrayStringParam) + }, + ani_native_function{ + "nativeSetArrayDoubleParam", "JLstd/core/String;Lescompat/Array;:Z", + reinterpret_cast(EtsWantParams::NativeSetArrayDoubleParam) + }, + ani_native_function{ + "nativeSetArrayIntParam", "JLstd/core/String;Lescompat/Array;:Z", + reinterpret_cast(EtsWantParams::NativeSetArrayIntParam) + }, + ani_native_function{ + "nativeSetArrayLongParam", "JLstd/core/String;Lescompat/Array;:Z", + reinterpret_cast(EtsWantParams::NativeSetArrayLongParam) + }, + ani_native_function{ + "nativeSetArrayBooleanParam", "JLstd/core/String;Lescompat/Array;:Z", + reinterpret_cast(EtsWantParams::NativeSetArrayBooleanParam) + }, + ani_native_function{ + "nativeSetArrayWantParams", "JLstd/core/String;Lescompat/Array;:Z", + reinterpret_cast(EtsWantParams::NativeSetArrayWantParams) + }, + ani_native_function{ + "nativeSetRemoteObjectParam", "JLstd/core/String;L@ohos/rpc/rpc/RemoteObject;:Z", + reinterpret_cast(EtsWantParams::NativeSetRemoteObjectParam) + }, + }; + status = aniEnv->Class_BindNativeMethods(nativeWantParamsCls, nativeFuncs.data(), nativeFuncs.size()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Class_BindNativeMethods failed status: %{public}d", status); + return status; + } + + ani_class nativeWantParamsCleanerCls = nullptr; + status = aniEnv->FindClass(ETS_NATIVE_WANT_PARAMS_CLEANER_CLASS_NAME, &nativeWantParamsCleanerCls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "FindClass NativeWantParams failed status: %{public}d", status); + return status; + } + std::array cleanerNativeFuncs = { + ani_native_function{ + "nativeDestroy", "J:V", + reinterpret_cast(EtsWantParams::NativeDestroy) + }, + }; + status = aniEnv->Class_BindNativeMethods(nativeWantParamsCleanerCls, cleanerNativeFuncs.data(), + cleanerNativeFuncs.size()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "Class_BindNativeMethods failed status: %{public}d", status); + return status; + } + return ANI_OK; +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + TAG_LOGD(AAFwkTag::WANT, "ANI_Constructor"); + ani_env *env = nullptr; + if (vm == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "null vm"); + return ANI_NOT_FOUND; + } + ani_status status = vm->GetEnv(ANI_VERSION_1, &env); + if (status != ANI_OK || env == nullptr) { + TAG_LOGE(AAFwkTag::WANT, "GetEnv failed status: %{public}d, or null env", status); + return status; + } + if ((status = BindNativeFunctions(env)) != ANI_OK) { + TAG_LOGE(AAFwkTag::WANT, "BindNativeFunctions failed status: %{public}d", status); + return status; + } + *result = ANI_VERSION_1; + return ANI_OK; +} +} +} // namespace OHOS::AppExecFwk diff --git a/frameworks/ets/ets/@ohos.app.ability.Want.ets b/frameworks/ets/ets/@ohos.app.ability.Want.ets index 6d7c75b3136927fa3172a881542c1cad61e42102..89350923dbce0a4f3f253870ff1c9ddcf1eac3bf 100644 --- a/frameworks/ets/ets/@ohos.app.ability.Want.ets +++ b/frameworks/ets/ets/@ohos.app.ability.Want.ets @@ -14,6 +14,7 @@ */ import hilog from '@ohos.hilog' +import rpc from '@ohos.rpc'; type valueType = NullishType; const DOMAIN_ID = 0xD001300; @@ -218,6 +219,177 @@ export class RecordSerializeTool { } } +class NativeWantParamsCleaner { + public nativeWantParams: long = 0; + + constructor(nativeWantParams: long) { + this.nativeWantParams = nativeWantParams; + } + + private static native nativeDestroy(nativeWantParams: long): void; + + public clean(): void { + NativeWantParamsCleaner.nativeDestroy(this.nativeWantParams); + this.nativeWantParams = 0; + } +} + +function nativeWantParamsCleanerCallback(cleaner: NativeWantParamsCleaner): void { + cleaner.clean(); +} + +let destroyRegister = new FinalizationRegistry(nativeWantParamsCleanerCallback); + +class NativeWantParams { + static { + loadLibrary("want_ani_kit.z"); + } + + private nativeWantParams: long = 0; + private cleaner: NativeWantParamsCleaner | null = null; + + constructor(wantParams?: long) { + if (wantParams === undefined) { + this.nativeWantParams = NativeWantParams.nativeCreate(); + this.registerCleaner(this.nativeWantParams) + return; + } + this.nativeWantParams = wantParams; + } + + private static native nativeCreate(): long; + + private static native nativeSetStringParam(nativeWantParams: long, key: string, value: string): boolean; + private static native nativeSetDoubleParam(nativeWantParams: long, key: string, value: double): boolean; + private static native nativeSetIntParam(nativeWantParams: long, key: string, value: int): boolean; + private static native nativeSetLongParam(nativeWantParams: long, key: string, value: long): boolean; + private static native nativeSetBooleanParam(nativeWantParams: long, key: string, value: boolean): boolean; + private static native nativeSetWantParams(nativeWantParams: long, key: string, value: long): boolean; + + private static native nativeSetArrayStringParam(nativeWantParams: long, key: string, value: Array): boolean; + private static native nativeSetArrayDoubleParam(nativeWantParams: long, key: string, value: Array): boolean; + private static native nativeSetArrayIntParam(nativeWantParams: long, key: string, value: Array): boolean; + private static native nativeSetArrayLongParam(nativeWantParams: long, key: string, value: Array): boolean; + private static native nativeSetArrayBooleanParam(nativeWantParams: long, key: string, value: Array): boolean; + private static native nativeSetArrayWantParams(nativeWantParams: long, key: string, value: Array): boolean; + + private static native nativeSetRemoteObjectParam( + nativeWantParams: long, key: string, value: rpc.RemoteObject): boolean; + + private registerCleaner(nativeWantParams: long): void { + this.cleaner = new NativeWantParamsCleaner(nativeWantParams); + destroyRegister.register(this, this.cleaner!, this); + } + + public setParam(key: string, value: string): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetStringParam(this.nativeWantParams, key, value); + } + + public setParam(key: string, value: double): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetDoubleParam(this.nativeWantParams, key, value); + } + + public setParam(key: string, value: int): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetIntParam(this.nativeWantParams, key, value); + } + + public setParam(key: string, value: long): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetLongParam(this.nativeWantParams, key, value); + } + + public setParam(key: string, value: boolean): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetBooleanParam(this.nativeWantParams, key, value); + } + + public setParam(key: string, value: NativeWantParams): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetWantParams(this.nativeWantParams, key, value.nativeWantParams); + } + + public SetArrayStringParam(key: string, value: Array): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetArrayStringParam(this.nativeWantParams, key, value); + } + + public SetArrayDoubleParam(key: string, value: Array): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetArrayDoubleParam(this.nativeWantParams, key, value); + } + + public SetArrayIntParam(key: string, value: Array): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetArrayIntParam(this.nativeWantParams, key, value); + } + + public SetArrayLongParam(key: string, value: Array): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetArrayLongParam(this.nativeWantParams, key, value); + } + + public SetArrayBooleanParam(key: string, value: Array): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetArrayBooleanParam(this.nativeWantParams, key, value); + } + + public SetArrayWantParams(key: string, value: Array): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + let nativeWantParams: Array = new Array(); + for (let item of value) { + nativeWantParams.push(item.nativeWantParams); + } + return NativeWantParams.nativeSetArrayWantParams(this.nativeWantParams, key, nativeWantParams); + } + + public setParam(key: string, value: rpc.RemoteObject): boolean { + if (this.nativeWantParams == 0) { + hilog.error(DOMAIN_ID, TAG, `nativeWantParams null`); + return false; + } + return NativeWantParams.nativeSetRemoteObjectParam(this.nativeWantParams, key, value); + } +} + export default class Want { bundleName?: string; abilityName?: string;