From e7f242ddc8e2b58217426f63318c7b65afcb4089 Mon Sep 17 00:00:00 2001 From: zhangzezhong Date: Tue, 17 Jun 2025 10:21:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0dialogRequest=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzezhong --- .../ets/ani/dialog_request_info/BUILD.gn | 60 +++++ .../include/ets_request_info.h | 42 +++ .../src/ets_request_info.cpp | 247 ++++++++++++++++++ .../ets/ani/ets_dialog_request/BUILD.gn | 72 +++++ .../include/ets_dialog_request.h | 26 ++ .../include/ets_dialog_request_callback.h | 26 ++ .../src/ets_dialog_request.cpp | 152 +++++++++++ .../src/ets_dialog_request_callback.cpp | 167 ++++++++++++ .../ets/@ohos.app.ability.dialogRequest.ets | 76 ++++++ frameworks/ets/ets/BUILD.gn | 18 ++ 10 files changed, 886 insertions(+) create mode 100644 frameworks/ets/ani/dialog_request_info/BUILD.gn create mode 100644 frameworks/ets/ani/dialog_request_info/include/ets_request_info.h create mode 100644 frameworks/ets/ani/dialog_request_info/src/ets_request_info.cpp create mode 100644 frameworks/ets/ani/ets_dialog_request/BUILD.gn create mode 100644 frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request.h create mode 100644 frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request_callback.h create mode 100644 frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request.cpp create mode 100644 frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request_callback.cpp create mode 100644 frameworks/ets/ets/@ohos.app.ability.dialogRequest.ets 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 00000000000..bf28252f101 --- /dev/null +++ b/frameworks/ets/ani/dialog_request_info/BUILD.gn @@ -0,0 +1,60 @@ +# Copyright (c) 2021-2022 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 00000000000..9a69874d7db --- /dev/null +++ b/frameworks/ets/ani/dialog_request_info/include/ets_request_info.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 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. + */ + +#ifndef OHOS_ABILITY_RUNTIME_REQUEST_INFO_H +#define OHOS_ABILITY_RUNTIME_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 00000000000..14c65409348 --- /dev/null +++ b/frameworks/ets/ani/dialog_request_info/src/ets_request_info.cpp @@ -0,0 +1,247 @@ +/* + * 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_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 CreateEtsLong(ani_env *env, ani_long value) +{ + ani_class persion_cls; + ani_status status = ANI_ERROR; + if ((status = env->FindClass("Lstd/core/Long;", &persion_cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::JSNAPI, "status : %{public}d", status); + return nullptr; + } + ani_method personInfoCtor; + if ((status = env->Class_FindMethod(persion_cls, "", "J:V", &personInfoCtor)) != ANI_OK) { + TAG_LOGE(AAFwkTag::JSNAPI, "status : %{public}d", status); + return nullptr; + } + ani_object personInfoObj; + if ((status = env->Object_New(persion_cls, personInfoCtor, &personInfoObj, value)) != ANI_OK) { + TAG_LOGE(AAFwkTag::JSNAPI, "status : %{public}d", status); + return nullptr; + } + return personInfoObj; +} + +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_ERROR; + 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::APPMGR, "null env"); + return nullptr; + } + if ((status = env->FindClass("L@ohos/app/ability/dialogRequest/dialogRequest/WindowRectInner;", &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "FindClass failed status : %{public}d", status); + return nullptr; + } + if (cls == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null cls"); + return nullptr; + } + if ((status = env->Class_FindMethod(cls, "", ":V", &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "find ctor failed status : %{public}d", status); + return nullptr; + } + if ((status = env->Object_New(cls, method, &object)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "Object_New failed status : %{public}d", status); + return nullptr; + } + if (object == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null object"); + return nullptr; + } + if (!SetWindowRect(env, object, left, top, width, height)) { + TAG_LOGE(AAFwkTag::APPMGR, "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"); + // return nullptr; + // } + + // ani_long param_value; + // ani_status status = ANI_ERROR; + // ani_class cls {}; + // ani_method method {}; + + // if ((status = env->FindClass("Lstd/core/Long;", &cls)) != ANI_OK) { + // TAG_LOGE(AAFwkTag::DIALOG, "FindClass failed status: %{public}d", status); + // return nullptr; + // } + // if ((status = env->Class_FindMethod(cls, "unboxed", nullptr, &method)) != ANI_OK) { + // TAG_LOGE(AAFwkTag::DIALOG, "Class_FindMethod failed status: %{public}d", status); + // return nullptr; + // } + // if ((status = env->Object_CallMethod_Long(etsParam, method, ¶m_value)) != ANI_OK) { + // TAG_LOGE(AAFwkTag::DIALOG, "Object_CallMethod_Long failed status: %{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); + 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 00000000000..d23a549cb78 --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/BUILD.gn @@ -0,0 +1,72 @@ +# Copyright (c) 2021-2022 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 00000000000..4956dea2436 --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 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. + */ + +#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 00000000000..5afeb018b99 --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request_callback.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 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. + */ +#ifndef OHOS_ABILITY_RUNTIME_DIALOG_REQUEST_CALLBACK_H +#define OHOS_ABILITY_RUNTIME_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 00000000000..062a38f1e2c --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request.cpp @@ -0,0 +1,152 @@ +/* + * 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(AAFwk::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::GetRequsetCallback) + }, + }; + status = env->Namespace_BindNativeMethod(ns, method.data(), method.size()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Namespace_BindNativeMethod 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 00000000000..1776461f8ce --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request_callback.cpp @@ -0,0 +1,167 @@ +/* + * 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_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 { // nameless +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; + ani_ref resultCodeRef; + 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) { + return; + } + TAG_LOGD(AAFwkTag::DIALOG, "processMode: %{public}d", resultCode); + + AAFwk::Want wantValue; + ani_boolean isWantUndefined; + 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; + ani_class cls {}; + ani_field nativeField = nullptr; + ani_status status = ANI_ERROR; + if (env == nullptr) { + return nullptr; + } + 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_FindField(cls, "nativeRequestCallback", &nativeField); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Class_FindField failed, status = %{public}d", status); + return nullptr; + } + status = env->Object_GetField_Long(object, nativeField, &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; + } +}; +} // nameless + +ani_object CreateEtsDialogRequestCallback(ani_env *env, const sptr &remoteObj) +{ + ani_object object = nullptr; + ani_method method = nullptr; + ani_class cls {}; + 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; + } + + ani_field nativeField = nullptr; + status = env->Class_FindField(cls, "nativeRequestCallback", &nativeField); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Class_FindField failed, status = %{public}d", status); + return nullptr; + } + status = env->Object_SetField_Long(object, nativeField, 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 00000000000..f15616479b1 --- /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 { + + 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 cf3a702bf83..16844f24c91 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("aability_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" ] @@ -897,6 +914,7 @@ group("ets_packages") { ":ability_runtime_ability_caller_abc_etc", ":ability_runtime_ability_constant_abc_etc", ":ability_runtime_ability_context_constant_abc_etc", + ":ability_runtime_ability_dialogRequest_abc_etc", ":ability_runtime_ability_stage_abc_etc", ":ability_runtime_ability_stage_context_abc_etc", ":ability_runtime_ability_stage_monitor_abc_etc", -- Gitee