From 3a43a037a9a198614e11bd606f605db5defd96d4 Mon Sep 17 00:00:00 2001 From: MoShangGongZi Date: Wed, 8 Nov 2023 15:41:52 +0000 Subject: [PATCH] =?UTF-8?q?UIExtension=E6=94=AF=E6=8C=81=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=8F=91=E9=80=81=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MoShangGongZi Change-Id: I8b2bfe6f792d53971ec7760670da11e3d0b34c10 Signed-off-by: MoShangGongZi --- frameworks/bridge/common/utils/utils.h | 6 + .../jsview/js_ui_extension.cpp | 110 ++++++++++++++++++ .../jsview/js_ui_extension.h | 3 + .../ui_extension/ui_extension_pattern.cpp | 76 +++++++++++- .../ui_extension/ui_extension_pattern.h | 8 +- .../ui_extension/ui_extension_proxy.cpp | 21 +++- .../pattern/ui_extension/ui_extension_proxy.h | 9 +- 7 files changed, 227 insertions(+), 6 deletions(-) diff --git a/frameworks/bridge/common/utils/utils.h b/frameworks/bridge/common/utils/utils.h index f40cb02de78..a94c611709f 100644 --- a/frameworks/bridge/common/utils/utils.h +++ b/frameworks/bridge/common/utils/utils.h @@ -88,6 +88,12 @@ constexpr int32_t ERROR_CODE_PAGE_STACK_FULL = 100003; // The pages are push constexpr int32_t ERROR_CODE_NAMED_ROUTE_ERROR = 100004; // Named route error. constexpr int32_t ERROR_CODE_URI_ERROR_LITE = 200002; // Uri error for lite. +// Send synchronous message error code +// No callback has been registered to process synchronous data transferring. +constexpr int32_t ERROR_CODE_UIEXTENSION_NOT_REGISTER_SYNC_CALLBACK = 100011; +// Transferring data failed +constexpr int32_t ERROR_CODE_UIEXTENSION_TRANSFER_DATA_FAILED = 100012; + // Drag event error code constexpr int32_t ERROR_CODE_DRAG_DATA_NOT_FOUND = 190001; // GetData failed, data not found. constexpr int32_t ERROR_CODE_DRAG_DATA_ERROR = 190002; // GetData failed, data error. diff --git a/frameworks/bridge/declarative_frontend/jsview/js_ui_extension.cpp b/frameworks/bridge/declarative_frontend/jsview/js_ui_extension.cpp index 199f1c7fae9..d6ed4b169c2 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_ui_extension.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_ui_extension.cpp @@ -17,6 +17,7 @@ #include #include +#include "want_params.h" #include "base/log/ace_scoring_log.h" #include "base/want/want_wrap.h" @@ -26,6 +27,7 @@ #include "core/common/container_scope.h" #include "core/components_ng/pattern/ui_extension/ui_extension_model.h" #include "core/components_ng/pattern/ui_extension/ui_extension_model_ng.h" +#include "interfaces/include/ws_common.h" namespace OHOS::Ace { std::unique_ptr UIExtensionModel::instance_ = nullptr; @@ -57,6 +59,9 @@ void JSUIExtensionProxy::JSBind(BindingTarget globalObj) { JSClass::Declare("UIExtensionProxy "); JSClass::CustomMethod("send", &JSUIExtensionProxy::Send); + JSClass::CustomMethod("sendSync", &JSUIExtensionProxy::SendSync); + JSClass::CustomMethod("on", &JSUIExtensionProxy::On); + JSClass::CustomMethod("off", &JSUIExtensionProxy::Off); JSClass::Bind(globalObj, &JSUIExtensionProxy::Constructor, &JSUIExtensionProxy::Destructor); } @@ -94,6 +99,111 @@ void JSUIExtensionProxy::Send(const JSCallbackInfo& info) } } +void JSUIExtensionProxy::SendSync(const JSCallbackInfo& info) +{ + if (info.Length() == 0 || !info[0]->IsObject()) { + return; + } + ContainerScope scope(instanceId_); + auto engine = EngineHelper::GetCurrentEngine(); + CHECK_NULL_VOID(engine); + NativeEngine* nativeEngine = engine->GetNativeEngine(); + CHECK_NULL_VOID(nativeEngine); + panda::Local value = info[0].Get().GetLocalHandle(); + JSValueWrapper valueWrapper = value; + ScopeRAII scopeNapi(reinterpret_cast(nativeEngine)); + napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper); + auto wantParams = WantParamsWrap::CreateWantWrap(reinterpret_cast(nativeEngine), nativeValue); + if (proxy_) { + AAFwk::WantParams reWantParams; + Rosen::WSErrorCode sendCode = proxy_->SendDataSync(wantParams, reWantParams); + if (sendCode != Rosen::WSErrorCode::WS_OK) { + const int32_t reErrorCode = static_cast(sendCode); + std::string errMsg; + if (reErrorCode == ERROR_CODE_UIEXTENSION_NOT_REGISTER_SYNC_CALLBACK) { + errMsg = "No callback has been registered to process synchronous data transferring."; + } else if (reErrorCode == ERROR_CODE_UIEXTENSION_TRANSFER_DATA_FAILED) { + errMsg = "Transferring data failed."; + } else { + errMsg = "Unknown error."; + } + JSException::Throw(reErrorCode, errMsg.c_str()); + return; + } + JSRef obj = JSRef::New(); + auto execCtx = info.GetExecutionContext(); + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + auto reNativeWantParams = + WantWrap::ConvertParamsToNativeValue(reWantParams, reinterpret_cast(nativeEngine)); + auto reWantParamsJSVal = Framework::JsConverter::ConvertNapiValueToJsVal(reNativeWantParams); + info.SetReturnValue(reWantParamsJSVal); + } +} + +void JSUIExtensionProxy::On(const JSCallbackInfo& info) +{ + const int argCount = 2; + if (info.Length() != argCount || !info[0]->IsString() || !info[1]->IsFunction()) { + return; + } + const std::string registerType = info[0]->ToString(); + auto jsFunc = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[1])); + auto instanceId = ContainerScope::CurrentId(); + auto onOnFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), instanceId] + (const RefPtr& session) { + ContainerScope scope(instanceId); + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + JSRef contextObj = JSClass::NewInstance(); + RefPtr proxy = Referenced::Claim(contextObj->Unwrap()); + proxy->SetInstanceId(instanceId); + proxy->SetProxy(session); + auto param = JSRef::Cast(contextObj); + func->ExecuteJS(1, ¶m); + }; + + auto pattern = proxy_->GetPattern(); + CHECK_NULL_VOID(pattern); + const std::string syncType = "syncReceiverRegister"; + const std::string asyncType = "asyncReceiverRegister"; + if (registerType == syncType) { + pattern->SetOnSyncOnCallback(std::move(onOnFunc)); + } else if (registerType == asyncType) { + pattern->SetOnAsyncOnCallback(std::move(onOnFunc)); + } +} + +void JSUIExtensionProxy::Off(const JSCallbackInfo& info) +{ + const int argCount = 2; + if (info.Length() != argCount || !info[0]->IsString() || !info[1]->IsFunction()) { + return; + } + const std::string registerType = info[0]->ToString(); + auto jsFunc = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[1])); + auto instanceId = ContainerScope::CurrentId(); + auto onOffFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), instanceId] + (const RefPtr& session) { + ContainerScope scope(instanceId); + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + JSRef contextObj = JSClass::NewInstance(); + RefPtr proxy = Referenced::Claim(contextObj->Unwrap()); + proxy->SetInstanceId(instanceId); + proxy->SetProxy(session); + auto param = JSRef::Cast(contextObj); + func->ExecuteJS(1, ¶m); + }; + + auto pattern = proxy_->GetPattern(); + CHECK_NULL_VOID(pattern); + const std::string syncType = "syncReceiverRegister"; + const std::string asyncType = "asyncReceiverRegister"; + if (registerType == syncType) { + pattern->SetOnSyncOffCallback(std::move(onOffFunc)); + } else if (registerType == asyncType) { + pattern->SetOnAsyncOffCallback(std::move(onOffFunc)); + } +} + void JSUIExtensionProxy::SetInstanceId(int32_t instanceId) { instanceId_ = instanceId; diff --git a/frameworks/bridge/declarative_frontend/jsview/js_ui_extension.h b/frameworks/bridge/declarative_frontend/jsview/js_ui_extension.h index 7f01ae737a9..e6dc8932245 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_ui_extension.h +++ b/frameworks/bridge/declarative_frontend/jsview/js_ui_extension.h @@ -38,6 +38,9 @@ public: ~JSUIExtensionProxy() override = default; static void JSBind(BindingTarget globalObj); void Send(const JSCallbackInfo& info); + void SendSync(const JSCallbackInfo& info); + void On(const JSCallbackInfo& info); + void Off(const JSCallbackInfo& info); void SetProxy(const RefPtr& proxy); void SetInstanceId(int32_t instanceId); private: diff --git a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.cpp b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.cpp index 451342bbbc7..09b23009e57 100755 --- a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.cpp +++ b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.cpp @@ -186,8 +186,10 @@ void UIExtensionPattern::OnConnect() host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); surfaceNode->CreateNodeInRenderThread(); auto pipeline = PipelineBase::GetCurrentContext(); + auto weak = WeakClaim(this); + auto pattern = weak.Upgrade(); if (onRemoteReadyCallback_) { - onRemoteReadyCallback_(MakeRefPtr(session_)); + onRemoteReadyCallback_(MakeRefPtr(session_, pattern)); } if (onModalRemoteReadyCallback_) { onModalRemoteReadyCallback_(std::make_shared(session_)); @@ -599,12 +601,82 @@ void UIExtensionPattern::SetOnRemoteReadyCallback(const std::functiononRemoteReadyCallback_) { - pattern->onRemoteReadyCallback_(MakeRefPtr(pattern->session_)); + pattern->onRemoteReadyCallback_(MakeRefPtr(pattern->session_, pattern)); } }, TaskExecutor::TaskType::UI); }; } +void UIExtensionPattern::SetOnSyncOnCallback(const std::function&)>&& callback) +{ + onSyncOnCallback_ = std::move(callback); + + auto pipeline = PipelineBase::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto taskExecutor = pipeline->GetTaskExecutor(); + CHECK_NULL_VOID(taskExecutor); + sptr extensionSession(static_cast(session_.GetRefPtr())); + auto extSessionEventCallback = extensionSession->GetExtensionSessionEventCallback(); + extSessionEventCallback->notifySyncOnFunc_ = + [weak = WeakClaim(this), instanceId = instanceId_, taskExecutor]() { + taskExecutor->PostTask([weak, instanceId]() { + ContainerScope scope(instanceId); + auto pattern = weak.Upgrade(); + if (pattern && pattern->onSyncOnCallback_) { + pattern->onSyncOnCallback_(MakeRefPtr(pattern->session_, pattern)); + } + }, TaskExecutor::TaskType::UI); + }; +} + +void UIExtensionPattern::SetOnAsyncOnCallback(const std::function&)>&& callback) +{ + onAsyncOnCallback_ = std::move(callback); + + auto pipeline = PipelineBase::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto taskExecutor = pipeline->GetTaskExecutor(); + CHECK_NULL_VOID(taskExecutor); + sptr extensionSession(static_cast(session_.GetRefPtr())); + auto extSessionEventCallback = extensionSession->GetExtensionSessionEventCallback(); + extSessionEventCallback->notifyAsyncOnFunc_ = + [weak = WeakClaim(this), instanceId = instanceId_, taskExecutor]() { + taskExecutor->PostTask([weak, instanceId]() { + ContainerScope scope(instanceId); + auto pattern = weak.Upgrade(); + if (pattern && pattern->onAsyncOnCallback_) { + pattern->onAsyncOnCallback_(MakeRefPtr(pattern->session_, pattern)); + } + }, TaskExecutor::TaskType::UI); + }; +} + +void UIExtensionPattern::SetOnSyncOffCallback(const std::function&)>&& callback) +{ + onSyncOnCallback_ = std::move(callback); + + auto pipeline = PipelineBase::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto taskExecutor = pipeline->GetTaskExecutor(); + CHECK_NULL_VOID(taskExecutor); + sptr extensionSession(static_cast(session_.GetRefPtr())); + auto extSessionEventCallback = extensionSession->GetExtensionSessionEventCallback(); + extSessionEventCallback->notifySyncOnFunc_ = nullptr; +} + +void UIExtensionPattern::SetOnAsyncOffCallback(const std::function&)>&& callback) +{ + onAsyncOnCallback_ = std::move(callback); + + auto pipeline = PipelineBase::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto taskExecutor = pipeline->GetTaskExecutor(); + CHECK_NULL_VOID(taskExecutor); + sptr extensionSession(static_cast(session_.GetRefPtr())); + auto extSessionEventCallback = extensionSession->GetExtensionSessionEventCallback(); + extSessionEventCallback->notifyAsyncOnFunc_ = nullptr; +} + void UIExtensionPattern::SetModalOnRemoteReadyCallback( const std::function&)>&& callback) { diff --git a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.h b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.h index 3c68f290ce5..ffb7b568057 100644 --- a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.h +++ b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.h @@ -67,8 +67,12 @@ public: void SetModalOnDestroy(const std::function&& callback); void SetModalOnRemoteReadyCallback( - const std::function&)>&& callback); + const std::function&)>&& callback); void SetOnRemoteReadyCallback(const std::function&)>&& callback); + void SetOnSyncOnCallback(const std::function&)>&& callback); + void SetOnAsyncOnCallback(const std::function&)>&& callback); + void SetOnSyncOffCallback(const std::function&)>&& callback); + void SetOnAsyncOffCallback(const std::function&)>&& callback); void SetOnReleaseCallback(const std::function&& callback); void SetOnResultCallback(const std::function&& callback); void SetOnReceiveCallback(const std::function&& callback); @@ -149,6 +153,8 @@ private: std::function onModalDestroy_; std::function&)> onModalRemoteReadyCallback_; std::function&)> onRemoteReadyCallback_; + std::function&)> onSyncOnCallback_; + std::function&)> onAsyncOnCallback_; std::function onReleaseCallback_; std::function onResultCallback_; std::function onReceiveCallback_; diff --git a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_proxy.cpp b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_proxy.cpp index fbc61162225..1c4c2938f2a 100644 --- a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_proxy.cpp +++ b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_proxy.cpp @@ -20,7 +20,8 @@ #include "adapter/ohos/osal/want_wrap_ohos.h" namespace OHOS::Ace::NG { -UIExtensionProxy::UIExtensionProxy(const sptr& session): session_(session) {} +UIExtensionProxy::UIExtensionProxy(const sptr& session, + const RefPtr& pattern): session_(session), pattern_(pattern) {} void UIExtensionProxy::SendData(const RefPtr& wantParams) { @@ -31,4 +32,22 @@ void UIExtensionProxy::SendData(const RefPtr& wantParams) extensionSession->TransferComponentData(params); } } + +OHOS::Rosen::WSErrorCode UIExtensionProxy::SendDataSync(const RefPtr& wantParams, + AAFwk::WantParams& reWantParams) +{ + Rosen::WSErrorCode transferCode = Rosen::WSErrorCode::WS_ERROR_TRANSFER_DATA_FAILED; + auto session = session_.promote(); + if (session) { + sptr extensionSession(static_cast(session.GetRefPtr())); + auto params = DynamicCast(wantParams)->GetWantParams(); + transferCode = extensionSession->TransferComponentDataSync(params, reWantParams); + } + return transferCode; +} + +RefPtr UIExtensionProxy::GetPattern() const +{ + return pattern_.Upgrade(); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_proxy.h b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_proxy.h index 50e511ebfef..8958c24b90a 100644 --- a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_proxy.h +++ b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_proxy.h @@ -21,9 +21,11 @@ #include "base/memory/ace_type.h" #include "base/memory/referenced.h" #include "base/want/want_wrap.h" +#include "ui_extension_pattern.h" namespace OHOS::Rosen { class Session; +enum class WSErrorCode : int32_t; } // namespace OHOS::Rosen namespace OHOS::Ace::NG { @@ -31,11 +33,14 @@ class UIExtensionProxy : public AceType { DECLARE_ACE_TYPE(UIExtensionProxy, AceType); public: - explicit UIExtensionProxy(const sptr& session); + UIExtensionProxy(const sptr& session, const RefPtr& pattern); void SendData(const RefPtr& params); - + OHOS::Rosen::WSErrorCode SendDataSync(const RefPtr& wantParams, + AAFwk::WantParams& reWantParams); + RefPtr GetPattern() const; private: wptr session_; + WeakPtr pattern_; }; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_UI_EXTENSION_UI_EXTENSION_PROXY_H -- Gitee