• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bridge/declarative_frontend/jsview/js_embedded_component.h"
17 
18 #include <cstdint>
19 #include <functional>
20 #include <string>
21 
22 #include "base/log/ace_scoring_log.h"
23 #include "base/log/log_wrapper.h"
24 #include "base/memory/ace_type.h"
25 #include "base/thread/task_executor.h"
26 #include "base/utils/utils.h"
27 #include "bridge/common/utils/engine_helper.h"
28 #include "bridge/declarative_frontend/engine/js_converter.h"
29 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
30 #include "bridge/declarative_frontend/engine/js_types.h"
31 #include "bridge/declarative_frontend/engine/jsi/jsi_ref.h"
32 #include "bridge/declarative_frontend/engine/jsi/jsi_types.h"
33 #include "bridge/declarative_frontend/jsview/js_ui_extension.h"
34 #include "bridge/declarative_frontend/jsview/js_utils.h"
35 #include "bridge/js_frontend/engine/jsi/js_value.h"
36 #include "core/common/container.h"
37 #include "core/common/container_scope.h"
38 #include "core/components_ng/pattern/ui_extension/ui_extension_model_ng.h"
39 #include "frameworks/core/components_ng/base/view_abstract_model.h"
40 
41 namespace OHOS::Ace::Framework {
42 const CalcDimension EMBEDDED_COMPONENT_MIN_WIDTH(10.0f, DimensionUnit::VP);
43 const CalcDimension EMBEDDED_COMPONENT_MIN_HEIGHT(10.0f, DimensionUnit::VP);
44 
JSBind(BindingTarget globalObj)45 void JSEmbeddedComponent::JSBind(BindingTarget globalObj)
46 {
47     JSClass<JSEmbeddedComponent>::Declare("EmbeddedComponent");
48     MethodOptions opt = MethodOptions::NONE;
49     JSClass<JSEmbeddedComponent>::StaticMethod("create", &JSEmbeddedComponent::Create, opt);
50     JSClass<JSEmbeddedComponent>::StaticMethod("onTerminated", &JSEmbeddedComponent::OnTerminated);
51     JSClass<JSEmbeddedComponent>::StaticMethod("onError", &JSEmbeddedComponent::OnError);
52     JSClass<JSEmbeddedComponent>::StaticMethod("width", &JSEmbeddedComponent::JsWidth);
53     JSClass<JSEmbeddedComponent>::StaticMethod("height", &JSEmbeddedComponent::JsHeight);
54     JSClass<JSEmbeddedComponent>::StaticMethod("constraintSize", &JSEmbeddedComponent::JsConstraintSize);
55     JSClass<JSEmbeddedComponent>::StaticMethod("aspectRatio", &JSEmbeddedComponent::JsAspectRatio);
56     JSClass<JSEmbeddedComponent>::StaticMethod("layoutWeight", &JSEmbeddedComponent::JsLayoutWeight);
57     JSClass<JSEmbeddedComponent>::StaticMethod("flexBasis", &JSEmbeddedComponent::JsFlexBasis);
58     JSClass<JSEmbeddedComponent>::StaticMethod("flexGrow", &JSEmbeddedComponent::JsFlexGrow);
59     JSClass<JSEmbeddedComponent>::StaticMethod("flexShrink", &JSEmbeddedComponent::JsFlexShrink);
60     JSClass<JSEmbeddedComponent>::StaticMethod("opacity", &JSEmbeddedComponent::JsOpacity);
61     JSClass<JSEmbeddedComponent>::InheritAndBind<JSViewAbstract>(globalObj);
62 }
63 
Create(const JSCallbackInfo & info)64 void JSEmbeddedComponent::Create(const JSCallbackInfo& info)
65 {
66     if (info.Length() < 1 || !info[0]->IsObject()) {
67         return;
68     }
69     auto wantObj = JSRef<JSObject>::Cast(info[0]);
70     RefPtr<OHOS::Ace::WantWrap> want = CreateWantWrapFromNapiValue(wantObj);
71 
72     NG::SessionType sessionType = NG::SessionType::EMBEDDED_UI_EXTENSION;
73     if (info.Length() > 1 && info[1]->IsNumber()) {
74         sessionType = static_cast<NG::SessionType>(info[1]->ToNumber<int32_t>());
75     }
76 
77     UIExtensionModel::GetInstance()->Create(want, sessionType);
78     ViewAbstractModel::GetInstance()->SetWidth(EMBEDDED_COMPONENT_MIN_WIDTH);
79     ViewAbstractModel::GetInstance()->SetHeight(EMBEDDED_COMPONENT_MIN_HEIGHT);
80     ViewAbstractModel::GetInstance()->SetMinWidth(EMBEDDED_COMPONENT_MIN_WIDTH);
81     ViewAbstractModel::GetInstance()->SetMinHeight(EMBEDDED_COMPONENT_MIN_HEIGHT);
82 }
83 
OnTerminated(const JSCallbackInfo & info)84 void JSEmbeddedComponent::OnTerminated(const JSCallbackInfo& info)
85 {
86     if (!info[0]->IsFunction()) {
87         return;
88     }
89     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
90     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
91     auto instanceId = ContainerScope::CurrentId();
92     auto onTerminated = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), instanceId, node = frameNode](
93                             int32_t code, const RefPtr<WantWrap>& wantWrap) {
94         ContainerScope scope(instanceId);
95         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
96         ACE_SCORING_EVENT("EmbeddedComponent.onTerminated");
97         auto pipelineContext = PipelineContext::GetCurrentContext();
98         CHECK_NULL_VOID(pipelineContext);
99         pipelineContext->UpdateCurrentActiveNode(node);
100         auto engine = EngineHelper::GetCurrentEngine();
101         CHECK_NULL_VOID(engine);
102         NativeEngine* nativeEngine = engine->GetNativeEngine();
103         CHECK_NULL_VOID(nativeEngine);
104         JSRef<JSObject> obj = JSRef<JSObject>::New();
105         obj->SetProperty<int32_t>("code", code);
106         if (wantWrap) {
107             auto nativeWant =
108                 WantWrap::ConvertToNativeValue(wantWrap->GetWant(), reinterpret_cast<napi_env>(nativeEngine));
109             auto wantJSVal = JsConverter::ConvertNapiValueToJsVal(nativeWant);
110             obj->SetPropertyObject("want", wantJSVal);
111         }
112         auto returnValue = JSRef<JSVal>::Cast(obj);
113         func->ExecuteJS(1, &returnValue);
114     };
115     UIExtensionModel::GetInstance()->SetOnTerminated(std::move(onTerminated));
116 }
117 
OnError(const JSCallbackInfo & info)118 void JSEmbeddedComponent::OnError(const JSCallbackInfo& info)
119 {
120     if (!info[0]->IsFunction()) {
121         return;
122     }
123     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
124     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
125     auto instanceId = ContainerScope::CurrentId();
126     auto onError = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), instanceId, node = frameNode](
127                        int32_t code, const std::string& name, const std::string& message) {
128         ContainerScope scope(instanceId);
129         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
130         ACE_SCORING_EVENT("EmbeddedComponent.onError");
131         auto pipelineContext = PipelineContext::GetCurrentContext();
132         CHECK_NULL_VOID(pipelineContext);
133         pipelineContext->UpdateCurrentActiveNode(node);
134         JSRef<JSObject> obj = JSRef<JSObject>::New();
135         obj->SetProperty<int32_t>("code", code);
136         obj->SetProperty<std::string>("name", name);
137         obj->SetProperty<std::string>("message", message);
138         auto returnValue = JSRef<JSVal>::Cast(obj);
139         func->ExecuteJS(FUNC_ARGC_1, &returnValue);
140     };
141     UIExtensionModel::GetInstance()->SetOnError(std::move(onError));
142 }
143 
JsWidth(const JSCallbackInfo & info)144 void JSEmbeddedComponent::JsWidth(const JSCallbackInfo& info)
145 {
146     if (info[0]->IsUndefined()) {
147         return;
148     }
149 
150     CalcDimension value;
151     if (JSViewAbstract::ParseJsDimensionVpNG(info[0], value)) {
152         ViewAbstractModel::GetInstance()->SetWidth(value);
153     }
154 }
155 
JsHeight(const JSCallbackInfo & info)156 void JSEmbeddedComponent::JsHeight(const JSCallbackInfo& info)
157 {
158     if (info[0]->IsUndefined()) {
159         return;
160     }
161 
162     CalcDimension value;
163     if (JSViewAbstract::ParseJsDimensionVpNG(info[0], value)) {
164         ViewAbstractModel::GetInstance()->SetHeight(value);
165     }
166 }
167 } // namespace OHOS::Ace::Framework
168