• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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