1 /*
2 * Copyright (c) 2022-2023 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 "core/components_ng/pattern/xcomponent/xcomponent_pattern.h"
17
18 #include "base/geometry/ng/size_t.h"
19 #include "base/ressched/ressched_report.h"
20 #include "base/utils/system_properties.h"
21 #include "base/utils/utils.h"
22 #include "bridge/declarative_frontend/declarative_frontend.h"
23 #include "core/components_ng/event/input_event.h"
24 #include "core/components_ng/pattern/xcomponent/xcomponent_event_hub.h"
25 #include "core/components_ng/pattern/xcomponent/xcomponent_ext_surface_callback_client.h"
26 #include "core/event/key_event.h"
27 #include "core/event/mouse_event.h"
28 #include "core/event/touch_event.h"
29 #include "core/pipeline_ng/pipeline_context.h"
30
31 namespace OHOS::Ace::NG {
32 namespace {
33 #ifdef OHOS_PLATFORM
34 constexpr int64_t INCREASE_CPU_TIME_ONCE = 4000000000; // 4s(unit: ns)
35 #endif
ConvertNativeXComponentTouchEvent(const TouchType & touchType)36 OH_NativeXComponent_TouchEventType ConvertNativeXComponentTouchEvent(const TouchType& touchType)
37 {
38 switch (touchType) {
39 case TouchType::DOWN:
40 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_DOWN;
41 case TouchType::UP:
42 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UP;
43 case TouchType::MOVE:
44 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_MOVE;
45 case TouchType::CANCEL:
46 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_CANCEL;
47 default:
48 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UNKNOWN;
49 }
50 }
51
ConvertNativeXComponentTouchToolType(const SourceTool & toolType)52 OH_NativeXComponent_TouchPointToolType ConvertNativeXComponentTouchToolType(const SourceTool& toolType)
53 {
54 switch (toolType) {
55 case SourceTool::FINGER:
56 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_FINGER;
57 case SourceTool::PEN:
58 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_PEN;
59 case SourceTool::RUBBER:
60 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_RUBBER;
61 case SourceTool::BRUSH:
62 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_BRUSH;
63 case SourceTool::PENCIL:
64 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_PENCIL;
65 case SourceTool::AIRBRUSH:
66 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_AIRBRUSH;
67 case SourceTool::MOUSE:
68 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_MOUSE;
69 case SourceTool::LENS:
70 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_LENS;
71 default:
72 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN;
73 }
74 }
75
ConvertNativeXComponentKeyAction(const KeyAction & keyAction)76 OH_NativeXComponent_KeyAction ConvertNativeXComponentKeyAction(const KeyAction& keyAction)
77 {
78 switch (keyAction) {
79 case KeyAction::DOWN:
80 return OH_NativeXComponent_KeyAction::OH_NATIVEXCOMPONENT_KEY_ACTION_DOWN;
81 case KeyAction::UP:
82 return OH_NativeXComponent_KeyAction::OH_NATIVEXCOMPONENT_KEY_ACTION_UP;
83 default:
84 return OH_NativeXComponent_KeyAction::OH_NATIVEXCOMPONENT_KEY_ACTION_UNKNOWN;
85 }
86 }
87
ConvertNativeXComponentEventSourceType(const SourceType & sourceType)88 OH_NativeXComponent_EventSourceType ConvertNativeXComponentEventSourceType(const SourceType& sourceType)
89 {
90 switch (sourceType) {
91 case SourceType::MOUSE:
92 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_MOUSE;
93 case SourceType::TOUCH:
94 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHSCREEN;
95 case SourceType::TOUCH_PAD:
96 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHPAD;
97 case SourceType::KEYBOARD:
98 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_KEYBOARD;
99 default:
100 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_UNKNOWN;
101 }
102 }
103
ConvertNativeXComponentKeyEvent(const KeyEvent & event)104 OH_NativeXComponent_KeyEvent ConvertNativeXComponentKeyEvent(const KeyEvent& event)
105 {
106 OH_NativeXComponent_KeyEvent nativeKeyEvent;
107 nativeKeyEvent.action = ConvertNativeXComponentKeyAction(event.action);
108 nativeKeyEvent.code = static_cast<OH_NativeXComponent_KeyCode>(event.code);
109 nativeKeyEvent.sourceType = ConvertNativeXComponentEventSourceType(event.sourceType);
110 nativeKeyEvent.deviceId = event.deviceId;
111 nativeKeyEvent.timestamp = event.timeStamp.time_since_epoch().count();
112 return nativeKeyEvent;
113 }
114 } // namespace
115
XComponentPattern(const std::string & id,XComponentType type,const std::string & libraryname,const RefPtr<XComponentController> & xcomponentController)116 XComponentPattern::XComponentPattern(const std::string& id, XComponentType type, const std::string& libraryname,
117 const RefPtr<XComponentController>& xcomponentController)
118 : id_(id), type_(type), libraryname_(libraryname), xcomponentController_(xcomponentController)
119 {}
120
OnAttachToFrameNode()121 void XComponentPattern::OnAttachToFrameNode()
122 {
123 auto host = GetHost();
124 CHECK_NULL_VOID(host);
125 auto renderContext = host->GetRenderContext();
126 if (type_ == XComponentType::SURFACE || type_ == XComponentType::TEXTURE) {
127 renderContext->SetClipToFrame(true);
128 renderContext->SetClipToBounds(true);
129 renderSurface_ = RenderSurface::Create();
130 instanceId_ = Container::CurrentId();
131 renderSurface_->SetInstanceId(instanceId_);
132 if (type_ == XComponentType::SURFACE) {
133 renderContextForSurface_ = RenderContext::Create();
134 static RenderContext::ContextParam param = { RenderContext::ContextType::HARDWARE_SURFACE,
135 id_ + "Surface" };
136 renderContextForSurface_->InitContext(false, param);
137 renderContextForSurface_->UpdateBackgroundColor(Color::BLACK);
138 if (!SystemProperties::GetExtSurfaceEnabled()) {
139 renderSurface_->SetRenderContext(renderContextForSurface_);
140 } else {
141 auto pipelineContext = PipelineContext::GetCurrentContext();
142 CHECK_NULL_VOID(pipelineContext);
143 pipelineContext->AddOnAreaChangeNode(host->GetId());
144 extSurfaceClient_ = MakeRefPtr<XComponentExtSurfaceCallbackClient>(WeakClaim(this));
145 renderSurface_->SetExtSurfaceCallback(extSurfaceClient_);
146 }
147 } else if (type_ == XComponentType::TEXTURE) {
148 renderSurface_->SetRenderContext(renderContext);
149 renderSurface_->SetIsTexture(true);
150 }
151 renderSurface_->InitSurface();
152 renderSurface_->UpdateXComponentConfig();
153 InitEvent();
154 SetMethodCall();
155 }
156 renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
157 }
158
OnAreaChangedInner()159 void XComponentPattern::OnAreaChangedInner()
160 {
161 if (SystemProperties::GetExtSurfaceEnabled()) {
162 auto host = GetHost();
163 CHECK_NULL_VOID(host);
164 auto geometryNode = host->GetGeometryNode();
165 CHECK_NULL_VOID(geometryNode);
166 auto xcomponentNodeSize = geometryNode->GetContentSize();
167 auto xcomponentNodeOffset = geometryNode->GetContentOffset();
168 auto transformRelativeOffset = host->GetTransformRelativeOffset();
169 renderSurface_->SetExtSurfaceBounds(transformRelativeOffset.GetX() + xcomponentNodeOffset.GetX(),
170 transformRelativeOffset.GetY() + xcomponentNodeOffset.GetY(), xcomponentNodeSize.Width(),
171 xcomponentNodeSize.Height());
172 }
173 }
174
OnRebuildFrame()175 void XComponentPattern::OnRebuildFrame()
176 {
177 if (type_ != XComponentType::SURFACE) {
178 return;
179 }
180 if (!renderSurface_->IsSurfaceValid()) {
181 LOGE("surface not valid");
182 return;
183 }
184 auto host = GetHost();
185 CHECK_NULL_VOID(host);
186 auto renderContext = host->GetRenderContext();
187 CHECK_NULL_VOID(renderContext);
188 CHECK_NULL_VOID(renderContextForSurface_);
189 renderContext->AddChild(renderContextForSurface_, 0);
190 }
191
OnDetachFromFrameNode(FrameNode * frameNode)192 void XComponentPattern::OnDetachFromFrameNode(FrameNode* frameNode)
193 {
194 CHECK_NULL_VOID(frameNode);
195 if (!hasXComponentInit_) {
196 return;
197 }
198 if (type_ == XComponentType::SURFACE || type_ == XComponentType::TEXTURE) {
199 NativeXComponentDestroy();
200 auto eventHub = frameNode->GetEventHub<XComponentEventHub>();
201 CHECK_NULL_VOID(eventHub);
202 eventHub->FireDestroyEvent();
203 }
204 }
205
SetMethodCall()206 void XComponentPattern::SetMethodCall()
207 {
208 CHECK_NULL_VOID(xcomponentController_);
209 auto pipelineContext = PipelineContext::GetCurrentContext();
210 CHECK_NULL_VOID(pipelineContext);
211 auto uiTaskExecutor = SingleTaskExecutor::Make(pipelineContext->GetTaskExecutor(), TaskExecutor::TaskType::UI);
212 xcomponentController_->SetConfigSurfaceImpl(
213 [weak = WeakClaim(this), uiTaskExecutor](uint32_t surfaceWidth, uint32_t surfaceHeight) {
214 uiTaskExecutor.PostSyncTask([weak, surfaceWidth, surfaceHeight]() {
215 auto pattern = weak.Upgrade();
216 CHECK_NULL_VOID(pattern);
217 pattern->ConfigSurface(surfaceWidth, surfaceHeight);
218 });
219 });
220
221 xcomponentController_->surfaceId_ = renderSurface_->GetUniqueId();
222 }
223
ConfigSurface(uint32_t surfaceWidth,uint32_t surfaceHeight)224 void XComponentPattern::ConfigSurface(uint32_t surfaceWidth, uint32_t surfaceHeight)
225 {
226 renderSurface_->ConfigSurface(surfaceWidth, surfaceHeight);
227 }
228
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)229 bool XComponentPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
230 {
231 if (type_ == XComponentType::COMPONENT || config.skipMeasure || dirty->SkipMeasureContent()) {
232 return false;
233 }
234 auto geometryNode = dirty->GetGeometryNode();
235 CHECK_NULL_RETURN(geometryNode, false);
236 auto drawSize = geometryNode->GetContentSize();
237 if (drawSize.IsNonPositive()) {
238 return false;
239 }
240
241 if (!hasXComponentInit_) {
242 initSize_ = drawSize;
243 auto position = geometryNode->GetContentOffset() + geometryNode->GetFrameOffset();
244 if (!SystemProperties::GetExtSurfaceEnabled()) {
245 XComponentSizeInit();
246 }
247 NativeXComponentOffset(position.GetX(), position.GetY());
248 hasXComponentInit_ = true;
249 } else {
250 if (config.frameOffsetChange || config.contentOffsetChange) {
251 auto position = geometryNode->GetContentOffset() + geometryNode->GetFrameOffset();
252 NativeXComponentOffset(position.GetX(), position.GetY());
253 }
254 if (config.contentSizeChange) {
255 if (!SystemProperties::GetExtSurfaceEnabled()) {
256 XComponentSizeChange(drawSize.Width(), drawSize.Height());
257 }
258 }
259 }
260 auto offset = geometryNode->GetContentOffset();
261 if (SystemProperties::GetExtSurfaceEnabled()) {
262 auto host = GetHost();
263 CHECK_NULL_RETURN(host, false);
264 auto transformRelativeOffset = host->GetTransformRelativeOffset();
265 renderSurface_->SetExtSurfaceBounds(static_cast<int32_t>(transformRelativeOffset.GetX() + offset.GetX()),
266 static_cast<int32_t>(transformRelativeOffset.GetY() + offset.GetY()),
267 static_cast<int32_t>(drawSize.Width()), static_cast<int32_t>(drawSize.Height()));
268 }
269 if (renderContextForSurface_) {
270 renderContextForSurface_->SetBounds(offset.GetX(), offset.GetY(), drawSize.Width(), drawSize.Height());
271 }
272 auto host = GetHost();
273 CHECK_NULL_RETURN(host, false);
274 host->MarkNeedSyncRenderTree();
275 return false;
276 }
277
OnPaint()278 void XComponentPattern::OnPaint()
279 {
280 auto host = GetHost();
281 CHECK_NULL_VOID(host);
282 auto renderContext = host->GetRenderContext();
283 renderContext->UpdateBackgroundColor(Color::BLACK);
284 }
285
NativeXComponentChange(float width,float height)286 void XComponentPattern::NativeXComponentChange(float width, float height)
287 {
288 CHECK_RUN_ON(UI);
289 CHECK_NULL_VOID(nativeXComponent_);
290 CHECK_NULL_VOID(nativeXComponentImpl_);
291 nativeXComponentImpl_->SetXComponentWidth(static_cast<int32_t>(width));
292 nativeXComponentImpl_->SetXComponentHeight(static_cast<int32_t>(height));
293 auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
294 const auto* callback = nativeXComponentImpl_->GetCallback();
295 CHECK_NULL_VOID_NOLOG(callback);
296 CHECK_NULL_VOID_NOLOG(callback->OnSurfaceChanged);
297 callback->OnSurfaceChanged(nativeXComponent_.get(), surface);
298 }
299
NativeXComponentDestroy()300 void XComponentPattern::NativeXComponentDestroy()
301 {
302 CHECK_RUN_ON(UI);
303 CHECK_NULL_VOID(nativeXComponent_);
304 CHECK_NULL_VOID(nativeXComponentImpl_);
305 auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
306 const auto* callback = nativeXComponentImpl_->GetCallback();
307 CHECK_NULL_VOID_NOLOG(callback);
308 CHECK_NULL_VOID_NOLOG(callback->OnSurfaceDestroyed);
309 callback->OnSurfaceDestroyed(nativeXComponent_.get(), surface);
310 }
311
NativeXComponentOffset(double x,double y)312 void XComponentPattern::NativeXComponentOffset(double x, double y)
313 {
314 CHECK_RUN_ON(UI);
315 CHECK_NULL_VOID(nativeXComponent_);
316 CHECK_NULL_VOID(nativeXComponentImpl_);
317 auto pipelineContext = PipelineContext::GetCurrentContext();
318 CHECK_NULL_VOID(pipelineContext);
319 float scale = pipelineContext->GetViewScale();
320 nativeXComponentImpl_->SetXComponentOffsetX(x * scale);
321 nativeXComponentImpl_->SetXComponentOffsetY(y * scale);
322 }
323
NativeXComponentDispatchTouchEvent(const OH_NativeXComponent_TouchEvent & touchEvent,const std::vector<XComponentTouchPoint> & xComponentTouchPoints)324 void XComponentPattern::NativeXComponentDispatchTouchEvent(
325 const OH_NativeXComponent_TouchEvent& touchEvent, const std::vector<XComponentTouchPoint>& xComponentTouchPoints)
326 {
327 CHECK_RUN_ON(UI);
328 CHECK_NULL_VOID(nativeXComponent_);
329 CHECK_NULL_VOID(nativeXComponentImpl_);
330 nativeXComponentImpl_->SetTouchEvent(touchEvent);
331 nativeXComponentImpl_->SetTouchPoint(xComponentTouchPoints);
332 auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
333 const auto* callback = nativeXComponentImpl_->GetCallback();
334 CHECK_NULL_VOID_NOLOG(callback);
335 CHECK_NULL_VOID_NOLOG(callback->DispatchTouchEvent);
336 callback->DispatchTouchEvent(nativeXComponent_.get(), surface);
337 }
338
InitNativeWindow(float textureWidth,float textureHeight)339 void XComponentPattern::InitNativeWindow(float textureWidth, float textureHeight)
340 {
341 auto context = PipelineContext::GetCurrentContext();
342 CHECK_NULL_VOID(context);
343 if (renderSurface_->IsSurfaceValid() && (type_ == XComponentType::SURFACE || type_ == XComponentType::TEXTURE)) {
344 float viewScale = context->GetViewScale();
345 renderSurface_->CreateNativeWindow();
346 renderSurface_->AdjustNativeWindowSize(
347 static_cast<uint32_t>(textureWidth * viewScale), static_cast<uint32_t>(textureHeight * viewScale));
348 }
349 }
350
XComponentSizeInit()351 void XComponentPattern::XComponentSizeInit()
352 {
353 CHECK_RUN_ON(UI);
354 ContainerScope scope(instanceId_);
355 auto context = PipelineContext::GetCurrentContext();
356 CHECK_NULL_VOID(context);
357 InitNativeWindow(initSize_.Width(), initSize_.Height());
358 auto host = GetHost();
359 CHECK_NULL_VOID(host);
360 auto eventHub = host->GetEventHub<XComponentEventHub>();
361 CHECK_NULL_VOID(eventHub);
362 eventHub->FireSurfaceInitEvent(id_, host->GetId());
363 eventHub->FireLoadEvent(id_);
364 }
365
XComponentSizeChange(float textureWidth,float textureHeight)366 void XComponentPattern::XComponentSizeChange(float textureWidth, float textureHeight)
367 {
368 ContainerScope scope(instanceId_);
369 auto context = PipelineContext::GetCurrentContext();
370 CHECK_NULL_VOID(context);
371 auto viewScale = context->GetViewScale();
372 renderSurface_->AdjustNativeWindowSize(
373 static_cast<uint32_t>(textureWidth * viewScale), static_cast<uint32_t>(textureHeight * viewScale));
374 NativeXComponentChange(textureWidth, textureHeight);
375 }
376
InitEvent()377 void XComponentPattern::InitEvent()
378 {
379 auto host = GetHost();
380 CHECK_NULL_VOID(host);
381 auto eventHub = host->GetEventHub<XComponentEventHub>();
382 CHECK_NULL_VOID(eventHub);
383 eventHub->SetOnSurfaceInitEvent(CreateExternalEvent());
384 auto gestureHub = eventHub->GetOrCreateGestureEventHub();
385 CHECK_NULL_VOID(gestureHub);
386 InitTouchEvent(gestureHub);
387 auto inputHub = eventHub->GetOrCreateInputEventHub();
388 InitMouseEvent(inputHub);
389 InitMouseHoverEvent(inputHub);
390 auto focusHub = host->GetOrCreateFocusHub();
391 CHECK_NULL_VOID(focusHub);
392 InitFocusEvent(focusHub);
393 }
394
InitFocusEvent(const RefPtr<FocusHub> & focusHub)395 void XComponentPattern::InitFocusEvent(const RefPtr<FocusHub>& focusHub)
396 {
397 auto onFocusEvent = [weak = WeakClaim(this)]() {
398 auto pattern = weak.Upgrade();
399 CHECK_NULL_VOID_NOLOG(pattern);
400 return pattern->HandleFocusEvent();
401 };
402 focusHub->SetOnFocusInternal(std::move(onFocusEvent));
403
404 auto onKeyEvent = [weak = WeakClaim(this)](const KeyEvent& event) -> bool {
405 auto pattern = weak.Upgrade();
406 CHECK_NULL_RETURN_NOLOG(pattern, false);
407 return pattern->HandleKeyEvent(event);
408 };
409 focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
410
411 auto onBlurEvent = [weak = WeakClaim(this)]() {
412 auto pattern = weak.Upgrade();
413 CHECK_NULL_VOID_NOLOG(pattern);
414 return pattern->HandleBlurEvent();
415 };
416 focusHub->SetOnBlurInternal(std::move(onBlurEvent));
417 }
HandleFocusEvent()418 void XComponentPattern::HandleFocusEvent()
419 {
420 CHECK_NULL_VOID(nativeXComponent_);
421 CHECK_NULL_VOID(nativeXComponentImpl_);
422 auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
423 const auto focusEventCallback = nativeXComponentImpl_->GetFocusEventCallback();
424 CHECK_NULL_VOID_NOLOG(focusEventCallback);
425 focusEventCallback(nativeXComponent_.get(), surface);
426 }
427
HandleKeyEvent(const KeyEvent & event)428 bool XComponentPattern::HandleKeyEvent(const KeyEvent& event)
429 {
430 CHECK_NULL_RETURN(nativeXComponent_, false);
431 CHECK_NULL_RETURN(nativeXComponentImpl_, false);
432
433 OH_NativeXComponent_KeyEvent keyEvent = ConvertNativeXComponentKeyEvent(event);
434 nativeXComponentImpl_->SetKeyEvent(keyEvent);
435
436 auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
437 const auto keyEventCallback = nativeXComponentImpl_->GetKeyEventCallback();
438 CHECK_NULL_RETURN_NOLOG(keyEventCallback, false);
439 keyEventCallback(nativeXComponent_.get(), surface);
440 return false;
441 }
442
HandleBlurEvent()443 void XComponentPattern::HandleBlurEvent()
444 {
445 CHECK_NULL_VOID(nativeXComponent_);
446 CHECK_NULL_VOID(nativeXComponentImpl_);
447 auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
448 const auto blurEventCallback = nativeXComponentImpl_->GetBlurEventCallback();
449 CHECK_NULL_VOID_NOLOG(blurEventCallback);
450 blurEventCallback(nativeXComponent_.get(), surface);
451 }
452
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)453 void XComponentPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
454 {
455 CHECK_NULL_VOID_NOLOG(!touchEvent_);
456
457 auto touchTask = [weak = WeakClaim(this)](const TouchEventInfo& info) {
458 auto pattern = weak.Upgrade();
459 CHECK_NULL_VOID(pattern);
460 pattern->HandleTouchEvent(info);
461 };
462
463 touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
464 gestureHub->AddTouchEvent(touchEvent_);
465 }
466
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)467 void XComponentPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
468 {
469 CHECK_NULL_VOID_NOLOG(!mouseEvent_);
470
471 auto mouseTask = [weak = WeakClaim(this)](const MouseInfo& info) {
472 auto pattern = weak.Upgrade();
473 CHECK_NULL_VOID(pattern);
474 pattern->HandleMouseEvent(info);
475 };
476
477 mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
478 inputHub->AddOnMouseEvent(mouseEvent_);
479 }
480
InitMouseHoverEvent(const RefPtr<InputEventHub> & inputHub)481 void XComponentPattern::InitMouseHoverEvent(const RefPtr<InputEventHub>& inputHub)
482 {
483 CHECK_NULL_VOID_NOLOG(!mouseHoverEvent_);
484 auto mouseHoverTask = [weak = WeakClaim(this)](bool isHover) {
485 auto pattern = weak.Upgrade();
486 CHECK_NULL_VOID(pattern);
487 pattern->HandleMouseHoverEvent(isHover);
488 };
489 mouseHoverEvent_ = MakeRefPtr<InputEvent>(std::move(mouseHoverTask));
490 inputHub->AddOnHoverEvent(mouseHoverEvent_);
491 }
492
HandleTouchEvent(const TouchEventInfo & info)493 void XComponentPattern::HandleTouchEvent(const TouchEventInfo& info)
494 {
495 auto touchInfoList = info.GetChangedTouches();
496 if (touchInfoList.empty()) {
497 return;
498 }
499 const auto& locationInfo = touchInfoList.front();
500 const auto& screenOffset = locationInfo.GetGlobalLocation();
501 const auto& localOffset = locationInfo.GetLocalLocation();
502 touchEventPoint_.id = locationInfo.GetFingerId();
503 touchEventPoint_.screenX = static_cast<float>(screenOffset.GetX());
504 touchEventPoint_.screenY = static_cast<float>(screenOffset.GetY());
505 touchEventPoint_.x = static_cast<float>(localOffset.GetX());
506 touchEventPoint_.y = static_cast<float>(localOffset.GetY());
507 touchEventPoint_.size = locationInfo.GetSize();
508 touchEventPoint_.force = locationInfo.GetForce();
509 touchEventPoint_.deviceId = locationInfo.GetTouchDeviceId();
510 const auto timeStamp = info.GetTimeStamp().time_since_epoch().count();
511 touchEventPoint_.timeStamp = timeStamp;
512 auto touchType = touchInfoList.front().GetTouchType();
513 touchEventPoint_.type = ConvertNativeXComponentTouchEvent(touchType);
514 #ifdef OHOS_PLATFORM
515 // increase cpu frequency
516 if (touchType == TouchType::MOVE) {
517 auto currentTime = GetSysTimestamp();
518 auto increaseCpuTime = currentTime - startIncreaseTime_;
519 if (increaseCpuTime >= INCREASE_CPU_TIME_ONCE) {
520 LOGD("HandleTouchEvent increase cpu frequency");
521 startIncreaseTime_ = currentTime;
522 ResSchedReport::GetInstance().ResSchedDataReport("slide_on");
523 }
524 } else if (touchType == TouchType::UP) {
525 startIncreaseTime_ = 0;
526 ResSchedReport::GetInstance().ResSchedDataReport("slide_off");
527 }
528 #endif
529 SetTouchPoint(info.GetTouches(), timeStamp, touchType);
530
531 if (nativeXComponent_ && nativeXComponentImpl_) {
532 nativeXComponentImpl_->SetHistoricalPoint(SetHistoryPoint(info.GetHistory()));
533 }
534 NativeXComponentDispatchTouchEvent(touchEventPoint_, nativeXComponentTouchPoints_);
535 }
536
HandleMouseEvent(const MouseInfo & info)537 void XComponentPattern::HandleMouseEvent(const MouseInfo& info)
538 {
539 OH_NativeXComponent_MouseEvent mouseEventPoint;
540 mouseEventPoint.x = static_cast<float>(info.GetLocalLocation().GetX());
541 mouseEventPoint.y = static_cast<float>(info.GetLocalLocation().GetY());
542 mouseEventPoint.screenX = static_cast<float>(info.GetScreenLocation().GetX());
543 mouseEventPoint.screenY = static_cast<float>(info.GetScreenLocation().GetY());
544 switch (info.GetAction()) {
545 case MouseAction::PRESS:
546 mouseEventPoint.action = OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_PRESS;
547 break;
548 case MouseAction::RELEASE:
549 mouseEventPoint.action = OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_RELEASE;
550 break;
551 case MouseAction::MOVE:
552 mouseEventPoint.action = OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_MOVE;
553 break;
554 default:
555 mouseEventPoint.action = OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_NONE;
556 break;
557 }
558 switch (info.GetButton()) {
559 case MouseButton::LEFT_BUTTON:
560 mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_LEFT_BUTTON;
561 break;
562 case MouseButton::RIGHT_BUTTON:
563 mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_RIGHT_BUTTON;
564 break;
565 case MouseButton::MIDDLE_BUTTON:
566 mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_MIDDLE_BUTTON;
567 break;
568 case MouseButton::BACK_BUTTON:
569 mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_BACK_BUTTON;
570 break;
571 case MouseButton::FORWARD_BUTTON:
572 mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_FORWARD_BUTTON;
573 break;
574 default:
575 mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_NONE_BUTTON;
576 break;
577 }
578 mouseEventPoint.timestamp = info.GetTimeStamp().time_since_epoch().count();
579 NativeXComponentDispatchMouseEvent(mouseEventPoint);
580 }
581
HandleMouseHoverEvent(bool isHover)582 void XComponentPattern::HandleMouseHoverEvent(bool isHover)
583 {
584 CHECK_RUN_ON(UI);
585 CHECK_NULL_VOID(nativeXComponent_);
586 CHECK_NULL_VOID(nativeXComponentImpl_);
587 const auto* callback = nativeXComponentImpl_->GetMouseEventCallback();
588 CHECK_NULL_VOID_NOLOG(callback);
589 CHECK_NULL_VOID_NOLOG(callback->DispatchHoverEvent);
590 callback->DispatchHoverEvent(nativeXComponent_.get(), isHover);
591 }
592
NativeXComponentDispatchMouseEvent(const OH_NativeXComponent_MouseEvent & mouseEvent)593 void XComponentPattern::NativeXComponentDispatchMouseEvent(const OH_NativeXComponent_MouseEvent& mouseEvent)
594 {
595 CHECK_RUN_ON(UI);
596 CHECK_NULL_VOID(nativeXComponent_);
597 CHECK_NULL_VOID(nativeXComponentImpl_);
598 nativeXComponentImpl_->SetMouseEvent(mouseEvent);
599 auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
600 const auto* callback = nativeXComponentImpl_->GetMouseEventCallback();
601 CHECK_NULL_VOID_NOLOG(callback);
602 CHECK_NULL_VOID_NOLOG(callback->DispatchMouseEvent);
603 callback->DispatchMouseEvent(nativeXComponent_.get(), surface);
604 }
605
SetTouchPoint(const std::list<TouchLocationInfo> & touchInfoList,const int64_t timeStamp,const TouchType & touchType)606 void XComponentPattern::SetTouchPoint(
607 const std::list<TouchLocationInfo>& touchInfoList, const int64_t timeStamp, const TouchType& touchType)
608 {
609 touchEventPoint_.numPoints =
610 touchInfoList.size() <= OH_MAX_TOUCH_POINTS_NUMBER ? touchInfoList.size() : OH_MAX_TOUCH_POINTS_NUMBER;
611 nativeXComponentTouchPoints_.clear();
612 uint32_t index = 0;
613 for (auto iterator = touchInfoList.begin(); iterator != touchInfoList.end() && index < OH_MAX_TOUCH_POINTS_NUMBER;
614 iterator++) {
615 OH_NativeXComponent_TouchPoint ohTouchPoint;
616 const auto& pointTouchInfo = *iterator;
617 const auto& pointScreenOffset = pointTouchInfo.GetGlobalLocation();
618 const auto& pointLocalOffset = pointTouchInfo.GetLocalLocation();
619 ohTouchPoint.id = pointTouchInfo.GetFingerId();
620 ohTouchPoint.screenX = static_cast<float>(pointScreenOffset.GetX());
621 ohTouchPoint.screenY = static_cast<float>(pointScreenOffset.GetY());
622 ohTouchPoint.x = static_cast<float>(pointLocalOffset.GetX());
623 ohTouchPoint.y = static_cast<float>(pointLocalOffset.GetY());
624 ohTouchPoint.type = ConvertNativeXComponentTouchEvent(touchType);
625 ohTouchPoint.size = pointTouchInfo.GetSize();
626 ohTouchPoint.force = pointTouchInfo.GetForce();
627 ohTouchPoint.timeStamp = timeStamp;
628 ohTouchPoint.isPressed = (touchType == TouchType::DOWN);
629 touchEventPoint_.touchPoints[index++] = ohTouchPoint;
630 // set tiltX, tiltY and sourceToolType
631 XComponentTouchPoint xcomponentTouchPoint;
632 xcomponentTouchPoint.tiltX = pointTouchInfo.GetTiltX().value_or(0.0f);
633 xcomponentTouchPoint.tiltY = pointTouchInfo.GetTiltY().value_or(0.0f);
634 xcomponentTouchPoint.sourceToolType = ConvertNativeXComponentTouchToolType(pointTouchInfo.GetSourceTool());
635 nativeXComponentTouchPoints_.emplace_back(xcomponentTouchPoint);
636 }
637 while (index < OH_MAX_TOUCH_POINTS_NUMBER) {
638 OH_NativeXComponent_TouchPoint ohTouchPoint;
639 ohTouchPoint.id = 0;
640 ohTouchPoint.screenX = 0;
641 ohTouchPoint.screenY = 0;
642 ohTouchPoint.x = 0;
643 ohTouchPoint.y = 0;
644 ohTouchPoint.type = OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UNKNOWN;
645 ohTouchPoint.size = 0;
646 ohTouchPoint.force = 0;
647 ohTouchPoint.timeStamp = 0;
648 ohTouchPoint.isPressed = false;
649 touchEventPoint_.touchPoints[index++] = ohTouchPoint;
650 }
651 }
652
SetHistoryPoint(const std::list<TouchLocationInfo> & touchInfoList)653 std::vector<OH_NativeXComponent_HistoricalPoint> XComponentPattern::SetHistoryPoint(
654 const std::list<TouchLocationInfo>& touchInfoList)
655 {
656 std::vector<OH_NativeXComponent_HistoricalPoint> historicalPoints;
657 for (auto&& item : touchInfoList) {
658 OH_NativeXComponent_HistoricalPoint point;
659 point.id = item.GetFingerId();
660 point.x = item.GetLocalLocation().GetX();
661 point.y = item.GetLocalLocation().GetY();
662 point.screenX = item.GetScreenLocation().GetX();
663 point.screenY = item.GetScreenLocation().GetY();
664 point.type = static_cast<OH_NativeXComponent_TouchEventType>(item.GetTouchType());
665 point.size = item.GetSize();
666 point.force = item.GetForce();
667 point.timeStamp = item.GetTimeStamp().time_since_epoch().count();
668 point.titlX = item.GetTiltX().value_or(0.0f);
669 point.titlY = item.GetTiltY().value_or(0.0f);
670 point.sourceTool = static_cast<OH_NativeXComponent_TouchEvent_SourceTool>(item.GetSourceTool());
671
672 historicalPoints.push_back(point);
673 }
674 return historicalPoints;
675 }
676
CreateExternalEvent()677 ExternalEvent XComponentPattern::CreateExternalEvent()
678 {
679 return [weak = AceType::WeakClaim(this), instanceId = instanceId_](
680 const std::string& componentId, const uint32_t nodeId, const bool isDestroy) {
681 ContainerScope scope(instanceId);
682 auto context = PipelineContext::GetCurrentContext();
683 CHECK_NULL_VOID(context);
684 auto frontEnd = AceType::DynamicCast<DeclarativeFrontend>(context->GetFrontend());
685 CHECK_NULL_VOID(frontEnd);
686 auto jsEngine = frontEnd->GetJsEngine();
687 jsEngine->FireExternalEvent(componentId, nodeId, isDestroy);
688 };
689 }
690 } // namespace OHOS::Ace::NG
691