diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index f487ec8a1225f3956c9d5fa7ec48d2bfa9ee867f..a2bfd2291e081634ba6f4e9f8a012e08d5a61a12 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -28,5 +28,6 @@ group("ani_packages") { "${ability_runtime_path}/frameworks/ets/ani/uri_permission_manager:uri_permission_manager_ani_kit", "${ability_runtime_path}/frameworks/ets/ani/wantagent:aniwantagent", "${ability_runtime_path}/frameworks/ets/ani/application:application_ani", + "${ability_runtime_path}/frameworks/ets/ani/ets_dialog_request:dialogrequest_ani_kit", ] } \ No newline at end of file diff --git a/frameworks/ets/ani/dialog_request_info/BUILD.gn b/frameworks/ets/ani/dialog_request_info/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..5a8309ed8afdaf967054a90de3b3a38e9a734fef --- /dev/null +++ b/frameworks/ets/ani/dialog_request_info/BUILD.gn @@ -0,0 +1,60 @@ +# 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("dialog_request_info_ani_kit") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + include_dirs = [ + "./include", + "${ability_runtime_services_path}/common/include", + ] + + configs = [ ] + + public_configs = [ ] + + sources = [ "./src/ets_request_info.cpp" ] + + deps = [ + "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + ] + + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + external_deps = [ + "ability_base:base", + "ability_base:want", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "runtime_core:ani", + ] + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "ability" + part_name = "ability_runtime" +} diff --git a/frameworks/ets/ani/dialog_request_info/include/ets_request_info.h b/frameworks/ets/ani/dialog_request_info/include/ets_request_info.h new file mode 100644 index 0000000000000000000000000000000000000000..1d996992c66a7d7d6051fc1ecc5470947485eb45 --- /dev/null +++ b/frameworks/ets/ani/dialog_request_info/include/ets_request_info.h @@ -0,0 +1,42 @@ +/* + * 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_ETS_REQUEST_INFO_H +#define OHOS_ABILITY_RUNTIME_ETS_REQUEST_INFO_H + +#include "iremote_object.h" +#include "sts_runtime.h" + +namespace OHOS { +namespace AbilityRuntime { +class RequestInfo { +public: + RequestInfo(const sptr &token, int32_t left, int32_t top, int32_t width, int32_t height); + ~RequestInfo(); + static ani_object WrapRequestInfo(ani_env *env, RequestInfo *request); + static std::shared_ptr UnwrapRequestInfo(ani_env *env, ani_object param); + sptr GetToken(); + static ani_object CreateEtsWindowRect( + ani_env *env, int32_t left, int32_t top, int32_t width, int32_t height); +private: + sptr callerToken_; + int32_t left_ = 0; + int32_t top_ = 0; + int32_t width_ = 0; + int32_t height_ = 0; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_REQUEST_INFO_H diff --git a/frameworks/ets/ani/dialog_request_info/src/ets_request_info.cpp b/frameworks/ets/ani/dialog_request_info/src/ets_request_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..898176a3a059ea0238d1bb64bb7bdf0abcdac9be --- /dev/null +++ b/frameworks/ets/ani/dialog_request_info/src/ets_request_info.cpp @@ -0,0 +1,195 @@ +/* + * 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 "ets_request_info.h" +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { + +RequestInfo::RequestInfo(const sptr &token, int32_t left, int32_t top, int32_t width, int32_t height) +{ + callerToken_ = token; + left_ = left; + top_ = top; + width_ = width; + height_ = height; +} + +RequestInfo::~RequestInfo() +{ +} + +sptr RequestInfo::GetToken() +{ + return callerToken_; +} + +ani_object RequestInfo::WrapRequestInfo(ani_env *env, RequestInfo *request) +{ + TAG_LOGD(AAFwkTag::DIALOG, "call"); + if (env == nullptr || request == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null input"); + return nullptr; + } + + ani_class cls {}; + ani_status status = env->FindClass("L@ohos/app/ability/dialogRequest/RequestInfoInner;", &cls); + if (status != ANI_OK || cls == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "FindClass failed: %{public}d", status); + return nullptr; + } + + ani_method ctorMethod = nullptr; + if ((status = env->Class_FindMethod(cls, "", ":V", &ctorMethod)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "find constructor failed: %{public}d", status); + return nullptr; + } + + ani_object result = nullptr; + if ((status = env->Object_New(cls, ctorMethod, &result)) != ANI_OK || result == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "Object_New failed: %{public}d", status); + return nullptr; + } + + ani_object windowRectObj = CreateEtsWindowRect(env, request->left_, request->top_, request->width_, request->height_); + if (windowRectObj == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "CreateEtsWindowRect failed"); + return nullptr; + } + if ((status = env->Object_SetPropertyByName_Ref(result, "windowRect", windowRectObj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "SetPropertyByName_Ref failed: %{public}d", status); + return nullptr; + } + + ani_field nativeField = nullptr; + if ((status = env->Class_FindField(cls, "nativeRequestInfo", &nativeField)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Class_FindField failed: %{public}d", status); + return nullptr; + } + if ((status = env->Object_SetField_Long(result, nativeField, reinterpret_cast(request))) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Object_SetField_Long failed: %{public}d", status); + return nullptr; + } + + return result; +} + +bool SetWindowRect(ani_env *env, + ani_object object, int32_t left, int32_t top, int32_t width, int32_t height) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "env is null"); + return false; + } + + ani_status status = ANI_OK; + if ((status = env->Object_SetPropertyByName_Double(object, "left", left)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "pid failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetPropertyByName_Double(object, "top", top)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "pid failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetPropertyByName_Double(object, "width", width)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "pid failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetPropertyByName_Double(object, "height", left)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "pid failed status:%{public}d", status); + return false; + } + return true; +} + +ani_object RequestInfo::CreateEtsWindowRect( + ani_env *env, int32_t left, int32_t top, int32_t width, int32_t height) +{ + TAG_LOGD(AAFwkTag::DIALOG, "left:%{public}d, top:%{public}d, width:%{public}d, height:%{public}d", + left, top, width, height); + ani_class cls {}; + ani_status status = ANI_ERROR; + ani_method method {}; + ani_object object = nullptr; + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null env"); + return nullptr; + } + if ((status = env->FindClass("L@ohos/app/ability/dialogRequest/dialogRequest/WindowRectInner;", &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "FindClass failed status : %{public}d", status); + return nullptr; + } + if (cls == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null cls"); + return nullptr; + } + if ((status = env->Class_FindMethod(cls, "", ":V", &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "find ctor failed status : %{public}d", status); + return nullptr; + } + if ((status = env->Object_New(cls, method, &object)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Object_New failed status : %{public}d", status); + return nullptr; + } + if (object == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null object"); + return nullptr; + } + if (!SetWindowRect(env, object, left, top, width, height)) { + TAG_LOGE(AAFwkTag::DIALOG, "SetWindowRect failed"); + return nullptr; + } + return object; +} + +std::shared_ptr RequestInfo::UnwrapRequestInfo(ani_env *env, ani_object etsParam) +{ + TAG_LOGI(AAFwkTag::DIALOG, "call"); + if (env == nullptr || etsParam == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null input"); + return nullptr; + } + + ani_class cls; + ani_status status = env->FindClass("L@ohos/app/ability/dialogRequest/RequestInfoInner;", &cls); + if (status != ANI_OK || cls == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "FindClass failed: %{public}d", status); + return nullptr; + } + + ani_field nativeField = nullptr; + if ((status = env->Class_FindField(cls, "nativeRequestInfo", &nativeField)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Class_FindField failed: %{public}d", status); + return nullptr; + } + + ani_long param_value = 0; + if ((status = env->Object_GetField_Long(etsParam, nativeField, ¶m_value)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Object_GetField_Long failed: %{public}d", status); + return nullptr; + } + + RequestInfo *info = reinterpret_cast(param_value); + if (info == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "info null"); + return nullptr; + } + + return std::make_shared(*info); +} + +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/ets_dialog_request/BUILD.gn b/frameworks/ets/ani/ets_dialog_request/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..991279db939997398ff0eb6f411759bb03148cfc --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/BUILD.gn @@ -0,0 +1,72 @@ +# 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("dialogrequest_ani_kit") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + include_dirs = [ + "./include", + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/frameworks/ets/ani/dialog_request_info/include", + "${ability_runtime_path}/frameworks/ets/ani/enum_convert", + ] + + configs = [] + + public_configs = [] + + configs = [ ] + + sources = [ + "./src/ets_dialog_request.cpp", + "./src/ets_dialog_request_callback.cpp", + ] + + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + deps = [ + "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + "${ability_runtime_native_path}/ability/native:abilitykit_native", + "${ability_runtime_native_path}/ability/native:dialog_request_callback", + "${ability_runtime_path}/frameworks/ets/ani/dialog_request_info:dialog_request_info_ani_kit", + ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "bundle_framework:appexecfwk_base", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "hilog:libhilog", + "ipc:ipc_core", + "ipc:ipc_napi", + "runtime_core:ani", + ] + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "ability" + part_name = "ability_runtime" +} diff --git a/frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request.h b/frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request.h new file mode 100644 index 0000000000000000000000000000000000000000..de1bbd8f4f64e485019fdabdb59c2ac70c16366f --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request.h @@ -0,0 +1,26 @@ +/* + * 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_ETS_DIALOG_REQUEST_H +#define OHOS_ABILITY_RUNTIME_ETS_DIALOG_REQUEST_H + +#include "sts_runtime.h" + +namespace OHOS { +namespace AbilityRuntime { +void EtsDialogRequestInit(ani_env *env); +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_DIALOG_REQUEST_H diff --git a/frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request_callback.h b/frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..2053c02cde558018bca386407c0e18ec30366921 --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request_callback.h @@ -0,0 +1,26 @@ +/* + * 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_ETS_DIALOG_REQUEST_CALLBACK_H +#define OHOS_ABILITY_RUNTIME_ETS_DIALOG_REQUEST_CALLBACK_H + +#include "idialog_request_callback.h" +#include "sts_runtime.h" + +namespace OHOS { +namespace AbilityRuntime { +ani_object CreateEtsDialogRequestCallback(ani_env *env, const sptr &remoteObj); +} // AbilityRuntime +} // OHOS +#endif // OHOS_ABILITY_RUNTIME_DIALOG_REQUEST_CALLBACK_H diff --git a/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request.cpp b/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bce2227a5118380227db02db89bf8a8863e59ecb --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2023-2024 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 "ets_dialog_request.h" + +#include "hilog_tag_wrapper.h" +#include "sts_error_utils.h" +#include "ets_dialog_request_callback.h" +#include "js_runtime_utils.h" +#include "ani_common_want.h" +#include "request_constants.h" +#include "ets_request_info.h" + +namespace OHOS { +namespace AbilityRuntime { + +class EtsDialogRequest final { +public: + EtsDialogRequest() = default; + ~EtsDialogRequest() = default; + + static ani_object GetRequestInfo(ani_env *env, ani_object wantEts) + { + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "env is nullptr"); + return nullptr; + } + + OHOS::AAFwk::Want want; + if (!OHOS::AppExecFwk::UnwrapWant(env, wantEts, want)) { + TAG_LOGE(AAFwkTag::DIALOG, "UnwrapWant failed"); + return nullptr; + } + + sptr callerToken = want.GetRemoteObject(RequestConstants::REQUEST_TOKEN_KEY); + if (!callerToken) { + TAG_LOGE(AAFwkTag::DIALOG, "get token from target wan failed"); + return nullptr; + } + int32_t left = want.GetIntParam(RequestConstants::WINDOW_RECTANGLE_LEFT_KEY, 0); + int32_t top = want.GetIntParam(RequestConstants::WINDOW_RECTANGLE_TOP_KEY, 0); + int32_t width = want.GetIntParam(RequestConstants::WINDOW_RECTANGLE_WIDTH_KEY, 0); + int32_t height = want.GetIntParam(RequestConstants::WINDOW_RECTANGLE_HEIGHT_KEY, 0); + + auto requestInfo = new RequestInfo(callerToken, left, top, width, height); + ani_object etsRequestInfo = RequestInfo::WrapRequestInfo(env, requestInfo); + if (etsRequestInfo == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "WrapRequestInfo failed"); + return nullptr; + } + return etsRequestInfo; + } + + static ani_object GetRequestCallback(ani_env *env, ani_object wantEts) + { + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "env is nullptr"); + return nullptr; + } + + OHOS::AAFwk::Want want; + if (!OHOS::AppExecFwk::UnwrapWant(env, wantEts, want)) { + TAG_LOGE(AAFwkTag::DIALOG, "The input want is invalid"); + return nullptr; + } + sptr remoteObj = want.GetRemoteObject(RequestConstants::REQUEST_CALLBACK_KEY); + if (!remoteObj) { + TAG_LOGE(AAFwkTag::DIALOG, "wrap requestCallback failed"); + return nullptr; + } + + sptr callback = iface_cast(remoteObj); + if (!callback) { + TAG_LOGE(AAFwkTag::DIALOG, "Cast to IDialogRequestCallback failed"); + AbilityRuntime::ThrowStsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return nullptr; + } + return CreateEtsDialogRequestCallback(env, callback); + } +}; + +void EtsDialogRequestInit(ani_env *env) +{ + TAG_LOGD(AAFwkTag::DIALOG, "EtsDialogRequestInit call"); + ani_status status = ANI_ERROR; + if (env->ResetError() != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "EtsDialogRequestInit ResetError failed"); + } + + ani_namespace ns; + status = env->FindNamespace("L@ohos/app/ability/dialogRequest/dialogRequest;", &ns); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "FindNamespace dialogRequest failed status : %{public}d", status); + return; + } + std::array method = { + ani_native_function {"getRequestInfo", + "L@ohos/app/ability/Want/Want;:L@ohos/app/ability/dialogRequest/dialogRequest/RequestInfo;", + reinterpret_cast(EtsDialogRequest::GetRequestInfo) + }, + ani_native_function {"getRequestCallback", + "L@ohos/app/ability/Want/Want;:L@ohos/app/ability/dialogRequest/dialogRequest/RequestCallback;", + reinterpret_cast(EtsDialogRequest::GetRequestCallback) + }, + }; + status = env->Namespace_BindNativeFunctions(ns, method.data(), method.size()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Namespace_BindNativeFunctions failed status : %{public}d", status); + } + if (env->ResetError() != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "ResetError failed"); + } +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "in EtsDualogRequest.ANI_Constructor"); + if (vm == nullptr || result == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null vm or result"); + return ANI_INVALID_ARGS; + } + + ani_env *env = nullptr; + ani_status status = ANI_ERROR; + status = vm->GetEnv(ANI_VERSION_1, &env); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "GetEnv failed, status=%{public}d", status); + return ANI_NOT_FOUND; + } + EtsDialogRequestInit(env); + *result = ANI_VERSION_1; + TAG_LOGD(AAFwkTag::ABILITYMGR, "EtsDualogRequest.ANI_Constructor finished"); + return ANI_OK; +} +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request_callback.cpp b/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0eaefd9c2a8f75d496d8cdae487ec64ad44b38ea --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request_callback.cpp @@ -0,0 +1,158 @@ +/* + * 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 "ets_dialog_request_callback.h" + +#include "hilog_tag_wrapper.h" +#include "sts_context_utils.h" +#include "sts_error_utils.h" +#include "js_runtime_utils.h" +#include "ani_common_want.h" +#include "ani_common_util.h" +#include "ani_enum_convert.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +class EtsDialogRequestCallback { +public: + explicit EtsDialogRequestCallback() = default; + + virtual ~EtsDialogRequestCallback() = default; + + static EtsDialogRequestCallback &GetInstance() + { + static EtsDialogRequestCallback instance; + return instance; + } + + static void SetRequestResult(ani_env *env,ani_object param, ani_object result) + { + if (env == nullptr || result == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null %{public}s", ((env == nullptr) ? "env" : "result")); + return; + } + GetInstance().OnSetRequestResult(env, param, result); + } + +private: + void OnSetRequestResult(ani_env *env, ani_object param, ani_object result) + { + TAG_LOGI(AAFwkTag::DIALOG, "call"); + ani_boolean isResultCodeUndefined = true; + ani_ref resultCodeRef = nullptr; + if (AppExecFwk::GetPropertyRef(env, result, "resultCode", resultCodeRef, isResultCodeUndefined) && isResultCodeUndefined) { + TAG_LOGE(AAFwkTag::DIALOG, " resultCode is undefined"); + return; + } + int32_t resultCode = 0; + ani_boolean isConvertSucess = false; + isConvertSucess = AAFwk::AniEnumConvertUtil::EnumConvertStsToNative( + env, reinterpret_cast(resultCodeRef), resultCode); + if (!isConvertSucess) { + TAG_LOGE(AAFwkTag::DIALOG, " EnumConvertStsToNative is failed"); + return; + } + TAG_LOGD(AAFwkTag::DIALOG, "processMode: %{public}d", resultCode); + + AAFwk::Want wantValue; + ani_boolean isWantUndefined = true; + ani_ref wantObject = nullptr; + if (AppExecFwk::GetPropertyRef(env, result, "want", wantObject, isWantUndefined) && !isWantUndefined) { + AppExecFwk::UnwrapWant(env, static_cast(wantObject), wantValue); + } else { + TAG_LOGW(AAFwkTag::DIALOG, "want is undefined"); + } + + sptr callback = GetDialogRequestCallback(env, param); + + if (callback == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "callback is null"); + return; + } + + callback->SendResult(resultCode, wantValue); + return; + } + + sptr GetDialogRequestCallback(ani_env *env, ani_object object) + { + ani_long nativeDialogRequest = 0; + ani_class cls = nullptr; + ani_field nativeField = nullptr; + ani_status status = ANI_ERROR; + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null env"); + return nullptr; + } + + status = env->Object_GetFieldByName_Long(object, "nativeRequestCallback", &nativeDialogRequest); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Object_SetField_Long failed, status = %{public}d", status); + return nullptr; + } + + auto pNativeDialogReq = reinterpret_cast(nativeDialogRequest); + auto nativeDialogReq = sptr(pNativeDialogReq); + return nativeDialogReq; + } +}; +} + +ani_object CreateEtsDialogRequestCallback(ani_env *env, const sptr &remoteObj) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null env"); + return nullptr; + } + ani_object object = nullptr; + ani_method method = nullptr; + ani_class cls = nullptr; + ani_status status = ANI_ERROR; + status = env->FindClass("L@ohos/app/ability/dialogRequest/dialogRequest/RequestCallbackInner;", &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "FindClass failed, status = %{public}d", status); + return nullptr; + } + status = env->Class_FindMethod(cls, "", ":V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "FindMethod failed, status = %{public}d", status); + return nullptr; + } + status = env->Object_New(cls, method, &object); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "ObjectNew failed, status = %{public}d", status); + return nullptr; + } + + std::array methods = { + ani_native_function {"setRequestResult", nullptr, reinterpret_cast(EtsDialogRequestCallback::SetRequestResult)}, + }; + + status = env->Class_BindNativeMethods(cls, methods.data(), methods.size()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Class_BindNativeMethod failed, status = %{public}d", status); + return nullptr; + } + + status = env->Object_SetFieldByName_Long(object, "nativeRequestCallback", reinterpret_cast(remoteObj.GetRefPtr())); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Object_SetField_Long failed, status = %{public}d", status); + return nullptr; + } + return object; +} +} // AbilityRuntime +} // OHOS diff --git a/frameworks/ets/ets/@ohos.app.ability.dialogRequest.ets b/frameworks/ets/ets/@ohos.app.ability.dialogRequest.ets new file mode 100644 index 0000000000000000000000000000000000000000..6bae8a10efbf383c952097e6a89972f1f6810a9a --- /dev/null +++ b/frameworks/ets/ets/@ohos.app.ability.dialogRequest.ets @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022-2023 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. + */ + +/** + * @file + * @kit AbilityKit + */ + +import Want from '@ohos.app.ability.Want'; + +namespace dialogRequest { + loadLibrary("dialogrequest_ani_kit.z"); + export interface WindowRect { + left: number; + top: number; + width: number; + height: number; + } + + export class WindowRectInner implements WindowRect { + left: number; + top: number; + width: number; + height: number; + } + + export interface RequestInfo { + windowRect?: WindowRect + } + + export class RequestInfoInner implements RequestInfo { + nativeRequestInfo: long = 0; + windowRect?: WindowRect; + } + + export enum ResultCode { + RESULT_OK = 0, + RESULT_CANCEL = 1 + } + + export interface RequestResult { + result: ResultCode; + want?: Want; + } + + export class RequestResultInner implements RequestResult { + result: ResultCode; + want?:Want; + } + + export interface RequestCallback { + setRequestResult(result: RequestResult): void; + } + + export class RequestCallbackInner implements RequestCallback { + nativeRequestCallback:long = 0; + public native setRequestResult(result: RequestResult): void; + } + + export native function getRequestInfo(want: Want): RequestInfo; + export native function getRequestCallback(want: Want): RequestCallback; +} + +export default dialogRequest; \ No newline at end of file diff --git a/frameworks/ets/ets/BUILD.gn b/frameworks/ets/ets/BUILD.gn index cf3a702bf832c0ccaefec72c9b95e6601fab2ebf..6225e74898f1df460fff977e68fa82140eb71656 100644 --- a/frameworks/ets/ets/BUILD.gn +++ b/frameworks/ets/ets/BUILD.gn @@ -261,6 +261,23 @@ ohos_prebuilt_etc("ability_runtime_ability_context_constant_abc_etc") { deps = [ ":ability_runtime_ability_context_constant_abc" ] } +generate_static_abc("ability_runtime_ability_dialogRequest_abc") { + base_url = "./" + files = [ "./@ohos.app.ability.dialogRequest.ets" ] + + is_boot_abc = "True" + device_dst_file = + "/system/framework/ability_runtime_ability_dialogRequest_abc.abc" +} + +ohos_prebuilt_etc("ability_runtime_ability_dialogRequest_abc_etc") { + source = "$target_out_dir/ability_runtime_ability_dialogRequest_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_runtime_ability_dialogRequest_abc" ] +} + generate_static_abc("ability_runtime_ui_ability_abc") { base_url = "./" files = [ "./@ohos.app.ability.UIAbility.ets" ] @@ -937,5 +954,6 @@ group("ets_packages") { ":ui_extension_ability_ani_etc", ":ability_runtime_OpenLink_Options_abc_etc", ":ability_runtime_AbilityRunningInfo_abc_etc", + ":ability_runtime_ability_dialogRequest_abc_etc", ] }