• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <memory>
17 
18 #include "frameworks/bridge/js_frontend/engine/v8/v8_xcomponent_bridge.h"
19 
20 #include "base/utils/string_utils.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22 #include "frameworks/bridge/js_frontend/engine/v8/v8_engine.h"
23 #include "frameworks/bridge/js_frontend/js_command.h"
24 #include "frameworks/core/common/ace_view.h"
25 #include "frameworks/core/common/container.h"
26 
27 namespace OHOS::Ace::Framework {
V8XComponentBridge()28 V8XComponentBridge::V8XComponentBridge()
29 {
30     nativeXComponentImpl_ = AceType::MakeRefPtr<NativeXComponentImpl>();
31     nativeXComponent_ = new OH_NativeXComponent(AceType::RawPtr(nativeXComponentImpl_));
32 }
33 
~V8XComponentBridge()34 V8XComponentBridge::~V8XComponentBridge()
35 {
36     if (nativeXComponent_) {
37         delete nativeXComponent_;
38         nativeXComponent_ = nullptr;
39     }
40 }
41 
HandleContext(const v8::Local<v8::Context> & ctx,NodeId id,const std::string & args,JsEngineInstance * engine)42 void V8XComponentBridge::HandleContext(const v8::Local<v8::Context>& ctx, NodeId id,
43                                        const std::string& args, JsEngineInstance* engine)
44 {
45     isolate_ = ctx->GetIsolate();
46     if (!isolate_) {
47         LOGE("V8XComponentBridge isolate_ is null.");
48         return;
49     }
50     ctx_.Reset(isolate_, ctx);
51 
52     if (hasPluginLoaded_) {
53         return;
54     }
55 
56     auto page = static_cast<RefPtr<JsAcePage>*>(ctx->GetIsolate()->GetData(V8EngineInstance::RUNNING_PAGE));
57     if (!page) {
58         LOGE("V8XComponentBridge page is null.");
59         return;
60     }
61     auto domXcomponent = AceType::DynamicCast<DOMXComponent>((*page)->GetDomDocument()->GetDOMNodeById(id));
62     if (!domXcomponent) {
63         LOGE("V8XComponentBridge domXcomponent is null.");
64         return;
65     }
66     auto xcomponent = AceType::DynamicCast<XComponentComponent>(domXcomponent->GetSpecializedComponent());
67     if (!xcomponent) {
68         LOGE("V8XComponentBridge xcomponent is null.");
69         return;
70     }
71     auto textureId = static_cast<int64_t>(xcomponent->GetTextureId());
72 
73     auto container = Container::Current();
74     if (!container) {
75         LOGE("V8XComponentBridge Current container null");
76         return;
77     }
78     auto nativeView = static_cast<AceView*>(container->GetView());
79     if (!nativeView) {
80         LOGE("V8XComponentBridge nativeView null");
81         return;
82     }
83     auto nativeWindow = const_cast<void*>(nativeView->GetNativeWindowById(textureId));
84     if (!nativeWindow) {
85         LOGE("V8XComponentBridge::HandleJsContext nativeWindow invalid");
86         return;
87     }
88 
89     nativeXComponentImpl_->SetSurface(nativeWindow);
90     nativeXComponentImpl_->SetXComponentId(xcomponent->GetId());
91 
92     std::shared_ptr<V8NativeEngine> nativeEngine = static_cast<V8EngineInstance*>(engine)->GetV8NativeEngine();
93     if (!nativeEngine) {
94         LOGE("nativeEngine is null");
95         return;
96     }
97 
98     auto renderContext = nativeEngine->LoadModuleByName(xcomponent->GetLibraryName(), true,
99                                                         args, OH_NATIVE_XCOMPONENT_OBJ,
100                                                         reinterpret_cast<void*>(nativeXComponent_));
101     renderContext_.Reset(isolate_, renderContext);
102     auto delegate = static_cast<RefPtr<FrontendDelegate>*>(isolate_->GetData(V8EngineInstance::FRONTEND_DELEGATE));
103     auto task = [weak = WeakClaim(this), xcomponent]() {
104         auto pool = xcomponent->GetTaskPool();
105         if (!pool) {
106             return;
107         }
108         auto bridge = weak.Upgrade();
109         if (bridge) {
110             pool->NativeXComponentInit(
111                 bridge->nativeXComponent_,
112                 AceType::WeakClaim(AceType::RawPtr(bridge->nativeXComponentImpl_)));
113         }
114     };
115     if (*delegate == nullptr) {
116         LOGE("delegate is null.");
117         return;
118     }
119     (*delegate)->PostSyncTaskToPage(task);
120     hasPluginLoaded_ = true;
121     return;
122 }
123 
JsGetXComponentSurfaceId(v8::Isolate * isolate,NodeId nodeId)124 v8::Local<v8::String> V8XComponentBridge::JsGetXComponentSurfaceId(v8::Isolate* isolate, NodeId nodeId)
125 {
126     if (!isolate) {
127         return v8::Local<v8::String>();
128     }
129     auto page = static_cast<RefPtr<JsAcePage>*>(isolate->GetData(V8EngineInstance::RUNNING_PAGE));
130     if (page == nullptr) {
131         return v8::Local<v8::String>();
132     }
133 
134     std::string surfaceId = "";
135     auto task = [nodeId, page, &surfaceId]() {
136         auto domDoc = (*page)->GetDomDocument();
137         if (!domDoc) {
138             return;
139         }
140         auto domXComponent = AceType::DynamicCast<DOMXComponent>(domDoc->GetDOMNodeById(nodeId));
141         if (!domXComponent) {
142             return;
143         }
144         surfaceId = domXComponent->GetSurfaceId();
145     };
146 
147     auto delegate = static_cast<RefPtr<FrontendDelegate>*>(isolate->GetData(V8EngineInstance::FRONTEND_DELEGATE));
148     if (delegate == nullptr) {
149         return v8::Local<v8::String>();
150     }
151     (*delegate)->PostSyncTaskToPage(task);
152 
153     return v8::String::NewFromUtf8(isolate, surfaceId.c_str()).ToLocalChecked();
154 }
155 
JsSetXComponentSurfaceSize(const v8::FunctionCallbackInfo<v8::Value> & args,const std::string & arguments,NodeId nodeId)156 void V8XComponentBridge::JsSetXComponentSurfaceSize(
157     const v8::FunctionCallbackInfo<v8::Value>& args, const std::string& arguments, NodeId nodeId)
158 {
159     v8::Isolate* isolate = args.GetIsolate();
160     if (isolate == nullptr) {
161         LOGE("JsSetXComponentSurfaceSize isolate is null!");
162         return;
163     }
164     v8::HandleScope handleScope(isolate);
165     auto context = isolate->GetCurrentContext();
166     if (context.IsEmpty()) {
167         LOGE("JsSetXComponentSurfaceSize context is empty!");
168         return;
169     }
170     v8::Local<v8::External> data = v8::Local<v8::External>::Cast(args.Data());
171     V8EngineInstance* engineInstance = static_cast<V8EngineInstance*>(data->Value());
172     if (engineInstance == nullptr) {
173         LOGE("JsSetXComponentSurfaceSize engineInstance is null!");
174         return;
175     }
176 
177     auto page = static_cast<RefPtr<JsAcePage>*>(isolate->GetData(V8EngineInstance::RUNNING_PAGE));
178     if (page == nullptr) {
179         LOGE("JsSetXComponentSurfaceSize page is null");
180         return;
181     }
182 
183     auto task = [nodeId, page, arguments]() {
184         auto domDoc = (*page)->GetDomDocument();
185         if (!domDoc) {
186             LOGE("JsSetXComponentSurfaceSize dom document is null!");
187             return;
188         }
189 
190         auto domXComponent = AceType::DynamicCast<DOMXComponent>(domDoc->GetDOMNodeById(nodeId));
191         if (!domXComponent) {
192             return;
193         }
194 
195         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(arguments);
196         if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() < 1) {
197             LOGE("JsSetXComponentSurfaceSize failed. parse args error");
198             return;
199         }
200         std::unique_ptr<JsonValue> surfaceSizePara = argsValue->GetArrayItem(0);
201         uint32_t surfaceWidth = surfaceSizePara->GetUInt("surfaceWidth", 0);
202         uint32_t surfaceHeight = surfaceSizePara->GetUInt("surfaceHeight", 0);
203         domXComponent->SetSurfaceSize(surfaceWidth, surfaceHeight);
204     };
205 
206     auto delegate = engineInstance->GetDelegate();
207     if (!delegate) {
208         LOGE("JsSetXComponentSurfaceSize delegate is null");
209         return;
210     }
211     delegate->PostSyncTaskToPage(task);
212 }
213 } // namespace OHOS::Ace::Framework