diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index 07051afaec8e5ccdd25d003cd2ed57805d429709..4ac40852bb8fe07e4c1252d7fdc226612556d7b1 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -43,5 +43,6 @@ group("ani_packages") { "${ability_runtime_path}/frameworks/ets/ani/wantagent:aniwantagent", "${ability_runtime_path}/frameworks/ets/ani/event_hub:event_hub_ani_kit", "${ability_runtime_path}/frameworks/ets/ani/apprecovery:appRecovery_ani", + "${ability_runtime_path}/frameworks/ets/ani/ets_dialog_request:dialogrequest_ani_kit", ] } diff --git a/frameworks/ets/ani/ani_common/include/ani_common_util.h b/frameworks/ets/ani/ani_common/include/ani_common_util.h index 492f91e1d97010276af41655f1cde6a4b91203c3..8ceb54ff614b8a7132f15d28061525a7e0df6429 100644 --- a/frameworks/ets/ani/ani_common/include/ani_common_util.h +++ b/frameworks/ets/ani/ani_common/include/ani_common_util.h @@ -90,6 +90,8 @@ bool IsValidProperty(ani_env *env, ani_ref param); bool CheckCallerIsSystemApp(); ani_object WrapLocale(ani_env *env, const std::string &locale); ani_object CreateIntAniArray(ani_env *env, const std::vector &dataArry); +ani_env* AttachAniEnv(ani_vm *etsVm); +void DetachAniEnv(ani_vm *etsVm); } // namespace AppExecFwk } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_ANI_COMMON_UTIL_H diff --git a/frameworks/ets/ani/ani_common/src/ani_common_util.cpp b/frameworks/ets/ani/ani_common/src/ani_common_util.cpp index 63b5c079f18600dfae6526c2d0bd2b186a1dcabe..51450474bce011756d8bf3779673d565870f726b 100644 --- a/frameworks/ets/ani/ani_common/src/ani_common_util.cpp +++ b/frameworks/ets/ani/ani_common/src/ani_common_util.cpp @@ -1533,5 +1533,37 @@ ani_object CreateIntAniArray(ani_env *env, const std::vector &dataArry) } return arrayObj; } + +ani_env* AttachAniEnv(ani_vm *etsVm) +{ + if (etsVm == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "etsVm nullptr"); + return nullptr; + } + ani_status status = ANI_ERROR; + ani_env *env = nullptr; + if ((status = etsVm->GetEnv(ANI_VERSION_1, &env)) == ANI_OK || env != nullptr) { + return env; + } + ani_option interopEnabled { "--interop=disable", nullptr }; + ani_options aniArgs { 1, &interopEnabled }; + if ((status = (etsVm->AttachCurrentThread(&aniArgs, ANI_VERSION_1, &env))) != ANI_OK || env == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "AttachCurrentThread status: %{public}d, or null env", status); + return nullptr; + } + return env; +} + +void DetachAniEnv(ani_vm *etsVm) +{ + if (etsVm == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "etsVm nullptr"); + return; + } + ani_status status = ANI_ERROR; + if ((status = etsVm->DetachCurrentThread()) != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "DetachCurrentThread status: %{public}d", status); + } +} } // namespace AppExecFwk } // namespace OHOS 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..ed4feb758b149d609031a6fbc2712923e96f49c4 --- /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 "ani.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..139d92c7b60f6f5708d0bea2bc9ccd1db7082cb1 --- /dev/null +++ b/frameworks/ets/ani/dialog_request_info/src/ets_request_info.cpp @@ -0,0 +1,185 @@ +/* + * 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, "", "J:V", &ctorMethod)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "find constructor failed: %{public}d", status); + return nullptr; + } + ani_long ptr = (ani_long)(request); + ani_object result = nullptr; + if ((status = env->Object_New(cls, ctorMethod, &result, ptr)) != 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; + } + + 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..e2f7b86325462ba9ca8169dc18c1d2c984027ebb --- /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 "ani.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..07f637b471eb352a274200527b92a900a4d91dfc --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/include/ets_dialog_request_callback.h @@ -0,0 +1,38 @@ +/* + * 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 "ani.h" + +namespace OHOS { +namespace AbilityRuntime { +class EtsDialogRequestCallback { +public: + explicit EtsDialogRequestCallback(const sptr remoteObj) :callback_(remoteObj) {} + virtual ~EtsDialogRequestCallback() = default; + static EtsDialogRequestCallback *GetEtsDialogReqCallback(ani_env *env, ani_object aniObj); + static void SetRequestResult(ani_env *env,ani_object param, ani_object result); +private: + void OnSetRequestResult(ani_env *env, ani_object param, ani_object result); + sptr GetDialogRequestCallback(ani_env *env, ani_object object); +private: + sptr callback_; +}; +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..406295c24c3655b5134713a77b2448141cf67493 --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request.cpp @@ -0,0 +1,203 @@ +/* + * 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 "ets_error_utils.h" +#include "ets_dialog_request_callback.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"); + EtsErrorUtil::ThrowInvalidParamError(env, "Parse param want failed, must be a Want."); + return nullptr; + } + sptr remoteObj = want.GetRemoteObject(RequestConstants::REQUEST_CALLBACK_KEY); + if (!remoteObj) { + TAG_LOGE(AAFwkTag::DIALOG, "wrap requestCallback failed"); + EtsErrorUtil::ThrowInvalidParamError(env, "Wrap Param requestCallback failed, must be a RequestCallback."); + return nullptr; + } + + sptr callback = iface_cast(remoteObj); + if (!callback) { + TAG_LOGE(AAFwkTag::DIALOG, "Cast to IDialogRequestCallback failed"); + EtsErrorUtil::ThrowInvalidParamError(env, "Cast to IDialogRequestCallback failed"); + return nullptr; + } + return CreateEtsDialogRequestCallback(env, callback); + } + + static void CleanToReqInfo(ani_env *env, ani_object object) + { + TAG_LOGD(AAFwkTag::DIALOG, "Clean Call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null env"); + return; + } + ani_long ptr = 0; + ani_status status = env->Object_GetFieldByName_Long(object, "ptr", &ptr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "ptr GetField status: %{public}d", status); + return; + } + if (ptr != 0) { + delete reinterpret_cast(ptr); + } + } + + static void CleanToReqCallback(ani_env *env, ani_object object) + { + TAG_LOGD(AAFwkTag::DIALOG, "Clean Call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "null env"); + return; + } + ani_long ptr = 0; + ani_status status = env->Object_GetFieldByName_Long(object, "ptr", &ptr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "ptr GetField status: %{public}d", status); + return; + } + if (ptr != 0) { + delete reinterpret_cast(ptr); + } + } +}; + +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); + return; + } + + ani_class cleanerCls = nullptr; + if ((status = env->FindClass( + "L@ohos/app/ability/dialogRequest/dialogRequest/Cleaner;", &cleanerCls)) != ANI_OK || cleanerCls == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "Cleaner FindClass failed status: %{public}d, or null cleanerCls", status); + return; + } + std::array cleanerMethods = { + ani_native_function {"cleanToReqInfo", nullptr, reinterpret_cast(EtsDialogRequest::CleanToReqInfo) }, + ani_native_function {"cleanToReqCallback", nullptr, reinterpret_cast(EtsDialogRequest::CleanToReqCallback) }, + }; + if ((status = env->Class_BindNativeMethods(cleanerCls, cleanerMethods.data(), cleanerMethods.size())) != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "Class_BindNativeMethods failed status: %{public}d", status); + return; + } + 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..2e11b4af22ca5f5ac1399d2f2bf8642201cf9065 --- /dev/null +++ b/frameworks/ets/ani/ets_dialog_request/src/ets_dialog_request_callback.cpp @@ -0,0 +1,136 @@ +/* + * 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 "ets_context_utils.h" +#include "ets_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 { +EtsDialogRequestCallback *EtsDialogRequestCallback::GetEtsDialogReqCallback(ani_env *env, ani_object aniObj) +{ + if (env == nullptr || aniObj == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null env or aniObj"); + EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER); + return nullptr; + } + ani_long dialogReqCallbackPtr = 0; + ani_status status = env->Object_GetFieldByName_Long(aniObj, "nativeRequestCallback", &dialogReqCallbackPtr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "nativeRequestCallback GetField status: %{public}d", status); + EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + return nullptr; + } + auto dialogReqCallback = reinterpret_cast(dialogReqCallbackPtr); + if (dialogReqCallback == nullptr) { + EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + TAG_LOGE(AAFwkTag::CONTEXT, "dialogReqCallback null"); + } + return dialogReqCallback; +} +void EtsDialogRequestCallback::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; + } + auto dialogReqCallback = GetEtsDialogReqCallback(env, param); + dialogReqCallback->OnSetRequestResult(env, param, result); +} +void EtsDialogRequestCallback::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, "result", resultCodeRef, isResultCodeUndefined) && isResultCodeUndefined) { + TAG_LOGE(AAFwkTag::DIALOG, " resultCode is undefined"); + return; + } + int32_t resultCode = 0; + ani_boolean isConvertSucess = false; + isConvertSucess = AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative( + env, reinterpret_cast(resultCodeRef), resultCode); + if (!isConvertSucess) { + TAG_LOGE(AAFwkTag::DIALOG, "Convert result failed"); + EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + 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 = callback_; + if (callback == nullptr) { + TAG_LOGE(AAFwkTag::DIALOG, "callback is null"); + EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER); + return; + } + callback->SendResult(resultCode, wantValue); + return; +} + +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, "", "J:V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DIALOG, "FindMethod failed, status = %{public}d", status); + return nullptr; + } + auto etsDialogRequestCallback = std::make_unique(remoteObj); + ani_long ptr = reinterpret_cast(etsDialogRequestCallback.release()); + status = env->Object_New(cls, method, &object, ptr); + 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 && status != ANI_ALREADY_BINDED) { + TAG_LOGE(AAFwkTag::DIALOG, "Class_BindNativeMethod failed, status = %{public}d", status); + return nullptr; + } + + return object; +} +} // AbilityRuntime +} // 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 b29b5117a647fa911c6d9c337bbde586ea220355..a3192cf118676c1c3032f26bd36818da25950221 100644 --- a/frameworks/ets/ani/ui_ability/include/ets_ability_context.h +++ b/frameworks/ets/ani/ui_ability/include/ets_ability_context.h @@ -130,6 +130,8 @@ public: ani_object callbackObj, ani_object startOptionsObj); static void StartRecentAbility(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object callbackObj, ani_object startOptionsObj); + static void RequestDialogService(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object call); + static ani_object WrapRequestDialogResult(ani_env *env, int32_t resultCode, const AAFwk::Want &want); #ifdef SUPPORT_GRAPHICS public: @@ -201,6 +203,7 @@ private: void UnwrapCompletionHandlerInStartOptions(ani_env *env, ani_object param, AAFwk::StartOptions &options); void CreateOnRequestResultCallback(ani_env *env, ani_ref refCompletionHandler, OnRequestResult &onRequestCallback, const char *callbackName); + void OnRequestDialogService(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object call); ani_env *env_ = nullptr; std::weak_ptr context_; 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 931eb6acdd4cd0dd57460135789aee9af1490978..87272b25557dbe7bac1009db728d4ceb495c7b9b 100644 --- a/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp +++ b/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp @@ -80,6 +80,12 @@ constexpr const char *SIGNATURE_START_ABILITY_AS_CALLER = "L@ohos/app/ability/Wa "Lutils/AbilityUtils/AsyncCallbackWrapper;L@ohos/app/ability/StartOptions/StartOptions;:V"; constexpr const char *SIGNATURE_START_RECENT_ABILITY = "L@ohos/app/ability/Want/Want;" "Lutils/AbilityUtils/AsyncCallbackWrapper;L@ohos/app/ability/StartOptions/StartOptions;:V"; +constexpr const char *REQUEST_RESULT_INNER_CLASS_NAME = + "L@ohos/app/ability/dialogRequest/dialogRequest/RequestResultInner;"; +constexpr const char *RESULT_ENUM_NAME = "L@ohos/app/ability/dialogRequest/dialogRequest/ResultCode;"; +constexpr const char *SIGNATURE_REQUEST_DIALOG_SERVICE = + "L@ohos/app/ability/Want/Want;Lutils/AbilityUtils/AsyncCallbackWrapper;:V"; + constexpr int32_t ARGC_ONE = 1; constexpr int32_t ARGC_TWO = 2; constexpr const char* SIGNATURE_RESTORE_WINDOW_STAGE = "Larkui/stateManagement/storage/localStorage/LocalStorage;:V"; @@ -246,6 +252,100 @@ EtsAbilityContext* EtsAbilityContext::GetEtsAbilityContext(ani_env *env, ani_obj return etsContext; } +void EtsAbilityContext::RequestDialogService(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object call) +{ + TAG_LOGD(AAFwkTag::CONTEXT, "RequestDialogService called"); + auto etsContext = GetEtsAbilityContext(env, aniObj); + if (etsContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null etsContext"); + return; + } + etsContext->OnRequestDialogService(env, aniObj, wantObj, call); +} + +ani_object EtsAbilityContext::WrapRequestDialogResult(ani_env *env, int32_t resultCode, const AAFwk::Want &want) +{ + ani_class requestResultInner = nullptr; + if (env == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null env"); + return nullptr; + } + ani_status status = env->FindClass(REQUEST_RESULT_INNER_CLASS_NAME, &requestResultInner); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "RequestResultInner FindClass status: %{public}d", status); + return nullptr; + } + ani_method method = nullptr; + if ((status = env->Class_FindMethod(requestResultInner, "", ":V", &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "RequestResultInner Class_FindMethod status: %{public}d", status); + return nullptr; + } + ani_object object = nullptr; + if ((status = env->Object_New(requestResultInner, method, &object)) != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "RequestResultInner Object_New status: %{public}d", status); + return nullptr; + } + ani_enum_item resultItem = nullptr; + if (!AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts(env, RESULT_ENUM_NAME, resultCode, resultItem) || + resultItem == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "resultItem failed, or null resultItem"); + return nullptr; + } + env->Object_SetPropertyByName_Ref(object, "result", resultItem); + env->Object_SetPropertyByName_Ref(object, "want", AppExecFwk::WrapWant(env, want)); + return object; +} + +void EtsAbilityContext::OnRequestDialogService(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object call) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null env"); + return; + } + AAFwk::Want want; + AppExecFwk::UnwrapWant(env, wantObj, want); + TAG_LOGD(AAFwkTag::CONTEXT, "target:%{public}s.%{public}s", want.GetBundle().c_str(), + want.GetElement().GetAbilityName().c_str()); + ani_vm *vm = nullptr; + ani_status status = env->GetVM(&vm); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "GetVM status: %{public}d", status); + return; + } + ani_ref callbackRef = nullptr; + env->GlobalReference_Create(call, &callbackRef); + RequestDialogResultTask task = + [vm, callbackRef](int32_t resultCode, const AAFwk::Want &resultWant) { + ani_env *env = AppExecFwk::AttachAniEnv(vm); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null env"); + return; + } + ani_object requestResult = EtsAbilityContext::WrapRequestDialogResult(env, resultCode, resultWant); + if (requestResult == nullptr) { + TAG_LOGW(AAFwkTag::CONTEXT, "null requestResult"); + EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER); + } else { + AppExecFwk::AsyncCallback(env, reinterpret_cast(callbackRef), nullptr, requestResult); + } + env->GlobalReference_Delete(callbackRef); + AppExecFwk::DetachAniEnv(vm); + TAG_LOGD(AAFwkTag::CONTEXT, "end async callback"); + }; + + auto context = context_.lock(); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "context null"); + EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + } else { + auto errCode = context->RequestDialogService(want, std::move(task)); + if (errCode != ERR_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "errCode: %{public}d", errCode); + EtsErrorUtil::ThrowError(env, EtsErrorUtil::CreateError(env, GetJsErrorCodeByNativeError(errCode))); + } + } +} + // to be done: free install void EtsAbilityContext::StartAbility(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object call) { @@ -2153,6 +2253,8 @@ bool BindNativeMethods(ani_env *env, ani_class &cls) reinterpret_cast(EtsAbilityContext::StartAbilityWithAccount) }, ani_native_function { "nativeStartAbilityWithAccountSync", SIGNATURE_START_ABILITY_WITH_ACCOUNT_OPTIONS, reinterpret_cast(EtsAbilityContext::StartAbilityWithAccountAndOptions) }, + ani_native_function { "nativeRequestDialogService", SIGNATURE_REQUEST_DIALOG_SERVICE, + reinterpret_cast(EtsAbilityContext::RequestDialogService) }, #ifdef SUPPORT_GRAPHICS ani_native_function { "nativeSetAbilityInstanceInfo", "Lstd/core/String;L@ohos/multimedia/image/image/PixelMap;Lutils/AbilityUtils/AsyncCallbackWrapper;:V", 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..51c23265d0468e049f7b7593963b038905d2ee2d --- /dev/null +++ b/frameworks/ets/ets/@ohos.app.ability.dialogRequest.ets @@ -0,0 +1,135 @@ +/* + * 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"); + + class Cleaner { + public ptr: long = 0; + + constructor(ptr: long) { + this.ptr = ptr; + } + + native cleanToReqInfo(): void; + native cleanToReqCallback(): void; + } + + export function callbackToReqInfo(cleaner: Cleaner): void { + cleaner.cleanToReqInfo(); + } + export function callbackToReqCallback(cleaner: Cleaner): void { + cleaner.cleanToReqCallback(); + } + + let destroyRegisterReqInfo = new FinalizationRegistry(callbackToReqInfo); + let unregisterTokenReqInfo = new object(); + + let destroyRegisterReqCallback = new FinalizationRegistry(callbackToReqCallback); + let unregisterTokenReqCallback = new object(); + + 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; + private cleaner: Cleaner | null = null; + + constructor(ptr: long) { + if (this.nativeRequestInfo == 0) { + this.nativeRequestInfo = ptr; + } + this.registerCleaner(this.nativeRequestInfo); + } + + registerCleaner(ptr: long): void { + this.cleaner = new Cleaner(ptr); + destroyRegisterReqInfo.register(this, this.cleaner!, unregisterTokenReqInfo); + } + + unregisterCleaner(): void { + destroyRegisterReqInfo.unregister(unregisterTokenReqInfo); + } + 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; + private cleaner: Cleaner | null = null; + + constructor(ptr: long) { + if (this.nativeRequestCallback == 0) { + this.nativeRequestCallback = ptr; + } + this.registerCleaner(this.nativeRequestCallback); + } + + registerCleaner(ptr: long): void { + this.cleaner = new Cleaner(ptr); + destroyRegisterReqCallback.register(this, this.cleaner!, unregisterTokenReqCallback); + } + + unregisterCleaner(): void { + destroyRegisterReqCallback.unregister(unregisterTokenReqCallback); + } + 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 e446b37c357a7870369507c4cc0f1174c6f0f66c..500704fd608701247a3cf6491ed12911dd608479 100644 --- a/frameworks/ets/ets/BUILD.gn +++ b/frameworks/ets/ets/BUILD.gn @@ -1559,6 +1559,23 @@ ohos_prebuilt_etc("ability_runtime_completion_handler_abc_etc") { deps = [ ":ability_runtime_completion_handler_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" ] +} + group("ets_packages") { deps = [ ":ability_application_abc_etc", @@ -1655,5 +1672,6 @@ group("ets_packages") { ":appRecovery_abc_etc", ":ability_runtime_mission_snapshot_abc_etc", ":ability_runtime_mission_listener_abc_etc", + ":ability_runtime_ability_dialogRequest_abc_etc", ] } diff --git a/frameworks/ets/ets/application/UIAbilityContext.ets b/frameworks/ets/ets/application/UIAbilityContext.ets index c32fcd8672ce0dff11d9ae451c690e6690839a2c..17a2bb3f88c12c3651d39933d79246d6297db393 100644 --- a/frameworks/ets/ets/application/UIAbilityContext.ets +++ b/frameworks/ets/ets/application/UIAbilityContext.ets @@ -31,6 +31,7 @@ import AbilityStartCallback from 'application.AbilityStartCallback'; import AtomicServiceOptions from '@ohos.app.ability.AtomicServiceOptions'; import image from '@ohos.multimedia.image'; import { LocalStorage } from '@ohos.arkui.stateManagement'; +import dialogRequest from '@ohos.app.ability.dialogRequest'; class Cleaner { public ptr: long = 0; @@ -181,6 +182,10 @@ export default class UIAbilityContext extends Context { callback: AsyncCallbackWrapper): void; private native nativeRestoreWindowStage(localStorage: LocalStorage): void; + + private native nativeRequestDialogService(want: Want, + result: AsyncCallbackWrapper): void; + private native nativeStartAbilityAsCaller(want: Want, callback: AsyncCallbackWrapper, options?: StartOptions): void; @@ -899,4 +904,32 @@ hideAbility(): Promise { }); }); } + + requestDialogService(want: Want, result: AsyncCallback): void { + let syncCall = new AsyncCallbackWrapper(result); + taskpool.execute((): void => { + this.nativeRequestDialogService(want, syncCall); + }).catch((err: BusinessError): void => { + result(err, undefined); + }); + } + + requestDialogService(want: Want): Promise { + return new Promise((resolve: (data: dialogRequest.RequestResult) => void, + reject: (err: BusinessError) => void): void => { + let syncCall = new AsyncCallbackWrapper((err: BusinessError | null, + data: dialogRequest.RequestResult | undefined) => { + if (err == null || err.code == 0) { + resolve(data as dialogRequest.RequestResult); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeRequestDialogService(want, syncCall); + }).catch((err: Error): void => { + reject(err as BusinessError); + }); + }); + } }