1 /*
2  * Copyright (c) 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 "core/components_ng/event/event_hub.h"
17 
18 #include "base/utils/utils.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/pipeline_ng/pipeline_context.h"
21 
22 namespace OHOS::Ace::NG {
23 
AttachHost(const WeakPtr<FrameNode> & host)24 void EventHub::AttachHost(const WeakPtr<FrameNode>& host)
25 {
26     host_ = host;
27 }
28 
OnAttachContext(PipelineContext * context)29 void EventHub::OnAttachContext(PipelineContext *context)
30 {
31     auto host = host_.Upgrade();
32     CHECK_NULL_VOID(host);
33     if (HasOnAreaChanged() || HasInnerOnAreaChanged()) {
34         context->AddOnAreaChangeNode(host->GetId());
35     }
36 
37     if (HasVisibleAreaCallback(true) || HasVisibleAreaCallback(false)) {
38         context->AddVisibleAreaChangeNode(host->GetId());
39     }
40 }
41 
OnDetachContext(PipelineContext * context)42 void EventHub::OnDetachContext(PipelineContext *context)
43 {
44     auto host = host_.Upgrade();
45     CHECK_NULL_VOID(host);
46     if (HasOnAreaChanged() || HasInnerOnAreaChanged()) {
47         context->RemoveOnAreaChangeNode(host->GetId());
48     }
49 
50     if (HasVisibleAreaCallback(true) || HasVisibleAreaCallback(false)) {
51         host->SetVisibleAreaChangeTriggerReason(VisibleAreaChangeTriggerReason::DETACH_FROM_MAINTREE);
52         host->TriggerVisibleAreaChangeCallback(0, true);
53         context->RemoveVisibleAreaChangeNode(host->GetId());
54     }
55 }
56 
GetFrameNode() const57 RefPtr<FrameNode> EventHub::GetFrameNode() const
58 {
59     return host_.Upgrade();
60 }
61 
AddSupportedState(UIState state)62 void EventHub::AddSupportedState(UIState state)
63 {
64     if (!stateStyleMgr_) {
65         stateStyleMgr_ = MakeRefPtr<StateStyleManager>(host_);
66     }
67     stateStyleMgr_->AddSupportedState(state);
68 }
69 
SetSupportedStates(UIState state)70 void EventHub::SetSupportedStates(UIState state)
71 {
72     if (!stateStyleMgr_) {
73         stateStyleMgr_ = MakeRefPtr<StateStyleManager>(host_);
74     }
75     stateStyleMgr_->SetSupportedStates(state);
76 }
77 
SetCurrentUIState(UIState state,bool flag)78 void EventHub::SetCurrentUIState(UIState state, bool flag)
79 {
80     if (!stateStyleMgr_) {
81         stateStyleMgr_ = MakeRefPtr<StateStyleManager>(host_);
82     }
83     stateStyleMgr_->SetCurrentUIState(state, flag);
84 }
85 
IsCurrentStateOn(UIState state)86 bool EventHub::IsCurrentStateOn(UIState state)
87 {
88     if (!stateStyleMgr_) {
89         return false;
90     }
91     return stateStyleMgr_->IsCurrentStateOn(state);
92 }
93 
CreateGetEventTargetImpl() const94 GetEventTargetImpl EventHub::CreateGetEventTargetImpl() const
95 {
96     auto impl = [weak = host_]() -> std::optional<EventTarget> {
97         auto host = weak.Upgrade();
98         CHECK_NULL_RETURN(host, std::nullopt);
99         EventTarget eventTarget;
100         eventTarget.id = std::to_string(host->GetId());
101         eventTarget.type = host->GetTag();
102         auto geometryNode = host->GetGeometryNode();
103         auto offset = geometryNode->GetFrameOffset();
104         auto size = geometryNode->GetFrameSize();
105         eventTarget.area.SetOffset(DimensionOffset(offset));
106         eventTarget.area.SetHeight(Dimension(size.Height()));
107         eventTarget.area.SetWidth(Dimension(size.Width()));
108         eventTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
109         return eventTarget;
110     };
111     return impl;
112 }
113 
PostEnabledTask()114 void EventHub::PostEnabledTask()
115 {
116     auto pipeline = PipelineBase::GetCurrentContext();
117     CHECK_NULL_VOID(pipeline);
118     auto taskExecutor = pipeline->GetTaskExecutor();
119     CHECK_NULL_VOID(taskExecutor);
120     taskExecutor->PostTask(
121         [weak = WeakClaim(this)]() {
122             auto eventHub = weak.Upgrade();
123             CHECK_NULL_VOID(eventHub);
124             eventHub->UpdateCurrentUIState(UI_STATE_DISABLED);
125         }, TaskExecutor::TaskType::UI, "ArkUIUpdateCurrentUIState");
126 }
127 
MarkModifyDone()128 void EventHub::MarkModifyDone()
129 {
130     if (stateStyleMgr_) {
131         // focused style is managered in focus event hub.
132         if (stateStyleMgr_->HasStateStyle(UI_STATE_PRESSED)) {
133             GetOrCreateGestureEventHub()->AddTouchEvent(stateStyleMgr_->GetPressedListener());
134         }
135         if (stateStyleMgr_->HasStateStyle(UI_STATE_DISABLED)) {
136             if (enabled_) {
137                 stateStyleMgr_->ResetCurrentUIState(UI_STATE_DISABLED);
138             } else {
139                 PostEnabledTask();
140             }
141         }
142     }
143 
144     if (gestureEventHub_) {
145         gestureEventHub_->OnModifyDone();
146     }
147     OnModifyDone();
148 }
149 
SetCustomerOnDragFunc(DragFuncType dragFuncType,OnDragFunc && onDragFunc)150 void EventHub::SetCustomerOnDragFunc(DragFuncType dragFuncType, OnDragFunc&& onDragFunc)
151 {
152     switch (dragFuncType) {
153         case DragFuncType::DRAG_ENTER:
154             customerOnDragEnter_ = std::move(onDragFunc);
155             break;
156         case DragFuncType::DRAG_LEAVE:
157             customerOnDragLeave_ = std::move(onDragFunc);
158             break;
159         case DragFuncType::DRAG_MOVE:
160             customerOnDragMove_ = std::move(onDragFunc);
161             break;
162         case DragFuncType::DRAG_DROP:
163             customerOnDrop_ = std::move(onDragFunc);
164             break;
165         default:
166             LOGW("unsuport dragFuncType");
167             break;
168     }
169 }
170 
SetCustomerOnDragFunc(DragFuncType dragFuncType,OnNewDragFunc && onDragEnd)171 void EventHub::SetCustomerOnDragFunc(DragFuncType dragFuncType, OnNewDragFunc&& onDragEnd)
172 {
173     if (dragFuncType != DragFuncType::DRAG_END) {
174         return;
175     }
176     customerOnDragEnd_ = std::move(onDragEnd);
177 }
178 
FireCustomerOnDragFunc(DragFuncType dragFuncType,const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)179 void EventHub::FireCustomerOnDragFunc(DragFuncType dragFuncType, const RefPtr<OHOS::Ace::DragEvent>& info,
180     const std::string& extraParams)
181 {
182     switch (dragFuncType) {
183         case DragFuncType::DRAG_ENTER: {
184             if (customerOnDragEnter_ != nullptr) {
185                 auto customerDragEnter = customerOnDragEnter_;
186                 customerDragEnter(info, extraParams);
187             }
188             break;
189         }
190         case DragFuncType::DRAG_LEAVE: {
191             if (customerOnDragLeave_ != nullptr) {
192                 auto customerOnDragLeave = customerOnDragLeave_;
193                 customerOnDragLeave(info, extraParams);
194             }
195             break;
196         }
197         case DragFuncType::DRAG_MOVE: {
198             if (customerOnDragMove_ != nullptr) {
199                 auto customerOnDragMove = customerOnDragMove_;
200                 customerOnDragMove(info, extraParams);
201             }
202             break;
203         }
204         case DragFuncType::DRAG_DROP: {
205             if (customerOnDrop_ != nullptr) {
206                 auto customerOnDrop = customerOnDrop_;
207                 customerOnDrop(info, extraParams);
208             }
209             break;
210         }
211         case DragFuncType::DRAG_END: {
212             if (customerOnDragEnd_ != nullptr) {
213                 auto customerOnDragEnd = customerOnDragEnd_;
214                 customerOnDragEnd(info);
215             }
216             break;
217         }
218         default:
219             LOGW("unsuport DragFuncType");
220             break;
221     }
222 }
223 
FireOnDragEnter(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)224 void EventHub::FireOnDragEnter(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
225 {
226     if (SystemProperties::GetDebugEnabled()) {
227         TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDragEnter");
228     }
229     if (onDragEnter_) {
230         // callback may be overwritten in its invoke so we copy it first
231         auto onDragEnter = onDragEnter_;
232         onDragEnter(info, extraParams);
233     }
234 }
235 
FireOnDragLeave(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)236 void EventHub::FireOnDragLeave(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
237 {
238     if (SystemProperties::GetDebugEnabled()) {
239         TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDragLeave");
240     }
241     if (onDragLeave_) {
242         // callback may be overwritten in its invoke so we copy it first
243         auto onDragLeave = onDragLeave_;
244         onDragLeave(info, extraParams);
245     }
246 }
247 
FireOnDragMove(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)248 void EventHub::FireOnDragMove(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
249 {
250     if (SystemProperties::GetDebugEnabled()) {
251         TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDragMove");
252     }
253     if (onDragMove_) {
254         // callback may be overwritten in its invoke so we copy it first
255         auto onDragMove = onDragMove_;
256         onDragMove(info, extraParams);
257     }
258 }
259 
FireOnDrop(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)260 void EventHub::FireOnDrop(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
261 {
262     if (SystemProperties::GetDebugEnabled()) {
263         TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDrop");
264     }
265     if (onDrop_) {
266         // callback may be overwritten in its invoke so we copy it first
267         auto onDrop = onDrop_;
268         onDrop(info, extraParams);
269     }
270 }
271 
IsFireOnDrop(const RefPtr<OHOS::Ace::DragEvent> & info)272 bool EventHub::IsFireOnDrop(const RefPtr<OHOS::Ace::DragEvent>& info)
273 {
274     return !HasCustomerOnDrop()
275         || info->GetResult() == DragRet::DRAG_DEFAULT
276         || info->GetResult() == DragRet::ENABLE_DROP
277         || info->GetResult() == DragRet::DISABLE_DROP;
278 }
279 
HandleInternalOnDrop(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)280 void EventHub::HandleInternalOnDrop(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
281 {
282     if (IsFireOnDrop(info)) {
283         FireOnDrop(info, extraParams);
284     }
285 }
286 
AddInnerOnAreaChangedCallback(int32_t id,OnAreaChangedFunc && callback)287 void EventHub::AddInnerOnAreaChangedCallback(int32_t id, OnAreaChangedFunc&& callback)
288 {
289     auto pipeline = PipelineContext::GetCurrentContext();
290     CHECK_NULL_VOID(pipeline);
291     auto frameNode = GetFrameNode();
292     CHECK_NULL_VOID(frameNode);
293     pipeline->AddOnAreaChangeNode(frameNode->GetId());
294     frameNode->InitLastArea();
295     onAreaChangedInnerCallbacks_[id] = std::move(callback);
296 }
297 
RemoveInnerOnAreaChangedCallback(int32_t id)298 void EventHub::RemoveInnerOnAreaChangedCallback(int32_t id)
299 {
300     CHECK_RUN_ON(UI);
301     onAreaChangedInnerCallbacks_.erase(id);
302 }
303 
ClearCustomerOnDragStart()304 void EventHub::ClearCustomerOnDragStart()
305 {
306     onDragStart_ = nullptr;
307 }
308 
ClearCustomerOnDragEnter()309 void EventHub::ClearCustomerOnDragEnter()
310 {
311     customerOnDragEnter_ = nullptr;
312 }
313 
ClearCustomerOnDragMove()314 void EventHub::ClearCustomerOnDragMove()
315 {
316     customerOnDragMove_ = nullptr;
317 }
318 
ClearCustomerOnDragLeave()319 void EventHub::ClearCustomerOnDragLeave()
320 {
321     customerOnDragLeave_ = nullptr;
322 }
323 
ClearCustomerOnDrop()324 void EventHub::ClearCustomerOnDrop()
325 {
326     customerOnDrop_ = nullptr;
327 }
328 
ClearCustomerOnDragEnd()329 void EventHub::ClearCustomerOnDragEnd()
330 {
331     customerOnDragEnd_ = nullptr;
332 }
333 
SetOnSizeChanged(OnSizeChangedFunc && onSizeChanged)334 void EventHub::SetOnSizeChanged(OnSizeChangedFunc&& onSizeChanged)
335 {
336     onSizeChanged_ = std::move(onSizeChanged);
337 }
338 
FireOnSizeChanged(const RectF & oldRect,const RectF & rect)339 void EventHub::FireOnSizeChanged(const RectF& oldRect, const RectF& rect)
340 {
341     if (onSizeChanged_) {
342         // callback may be overwritten in its invoke so we copy it first
343         auto onSizeChanged = onSizeChanged_;
344         onSizeChanged(oldRect, rect);
345     }
346 }
347 
SetJSFrameNodeOnSizeChangeCallback(OnSizeChangedFunc && onSizeChanged)348 void EventHub::SetJSFrameNodeOnSizeChangeCallback(OnSizeChangedFunc&& onSizeChanged)
349 {
350     onJsFrameNodeSizeChanged_ = std::move(onSizeChanged);
351 }
352 
FireJSFrameNodeOnSizeChanged(const RectF & oldRect,const RectF & rect)353 void EventHub::FireJSFrameNodeOnSizeChanged(const RectF& oldRect, const RectF& rect)
354 {
355     if (onJsFrameNodeSizeChanged_) {
356         // callback may be overwritten in its invoke so we copy it first
357         auto onSizeChanged = onJsFrameNodeSizeChanged_;
358         onSizeChanged(oldRect, rect);
359     }
360 }
361 
ClearJSFrameNodeOnSizeChange()362 void EventHub::ClearJSFrameNodeOnSizeChange()
363 {
364     if (onJsFrameNodeSizeChanged_) {
365         onJsFrameNodeSizeChanged_ = nullptr;
366     }
367 }
368 
HasOnSizeChanged() const369 bool EventHub::HasOnSizeChanged() const
370 {
371     return static_cast<bool>(onSizeChanged_) || static_cast<bool>(onJsFrameNodeSizeChanged_);
372 }
373 
HasImmediatelyVisibleCallback()374 bool EventHub::HasImmediatelyVisibleCallback()
375 {
376     return visibleAreaUserCallback_.callback || visibleAreaInnerCallback_.callback;
377 }
378 
ClearOnAreaChangedInnerCallbacks()379 void EventHub::ClearOnAreaChangedInnerCallbacks()
380 {
381     onAreaChangedInnerCallbacks_.clear();
382 }
383 
ClearCustomerOnDragFunc()384 void EventHub::ClearCustomerOnDragFunc()
385 {
386     onDragStart_ = nullptr;
387     customerOnDragEnter_ = nullptr;
388     customerOnDragLeave_ = nullptr;
389     customerOnDragMove_ = nullptr;
390     customerOnDrop_ = nullptr;
391     customerOnDragEnd_ = nullptr;
392 }
393 
SetJSFrameNodeOnAppear(std::function<void ()> && onAppear)394 void EventHub::SetJSFrameNodeOnAppear(std::function<void()>&& onAppear)
395 {
396     onJSFrameNodeAppear_ = std::move(onAppear);
397 }
398 
ClearJSFrameNodeOnAppear()399 void EventHub::ClearJSFrameNodeOnAppear()
400 {
401     if (onJSFrameNodeAppear_) {
402         onJSFrameNodeAppear_ = nullptr;
403     }
404 }
405 
SetJSFrameNodeOnDisappear(std::function<void ()> && onDisappear)406 void EventHub::SetJSFrameNodeOnDisappear(std::function<void()>&& onDisappear)
407 {
408     onJSFrameNodeDisappear_ = std::move(onDisappear);
409 }
410 
ClearJSFrameNodeOnDisappear()411 void EventHub::ClearJSFrameNodeOnDisappear()
412 {
413     if (onJSFrameNodeDisappear_) {
414         onJSFrameNodeDisappear_ = nullptr;
415     }
416 }
417 
FireOnAppear()418 void EventHub::FireOnAppear()
419 {
420     if (onAppear_ || onJSFrameNodeAppear_) {
421         auto pipeline = PipelineBase::GetCurrentContextSafely();
422         CHECK_NULL_VOID(pipeline);
423         auto taskScheduler = pipeline->GetTaskExecutor();
424         CHECK_NULL_VOID(taskScheduler);
425         taskScheduler->PostTask(
426             [weak = WeakClaim(this)]() {
427                 auto eventHub = weak.Upgrade();
428                 CHECK_NULL_VOID(eventHub);
429                 if (eventHub->onAppear_) {
430                     // callback may be overwritten in its invoke so we copy it first
431                     auto onAppear = eventHub->onAppear_;
432                     onAppear();
433                 }
434                 if (eventHub->onJSFrameNodeAppear_) {
435                     // callback may be overwritten in its invoke so we copy it first
436                     auto onJSFrameNodeAppear = eventHub->onJSFrameNodeAppear_;
437                     onJSFrameNodeAppear();
438                 }
439             },
440             TaskExecutor::TaskType::UI, "ArkUIFrameNodeAppearEvent");
441     }
442 }
443 
FireOnDisappear()444 void EventHub::FireOnDisappear()
445 {
446     if (onDisappear_) {
447         // callback may be overwritten in its invoke so we copy it first
448         auto onDisappear = onDisappear_;
449         onDisappear();
450     }
451     if (onJSFrameNodeDisappear_) {
452         // callback may be overwritten in its invoke so we copy it first
453         auto onJSFrameNodeDisappear = onJSFrameNodeDisappear_;
454         onJSFrameNodeDisappear();
455     }
456 }
457 
AddInnerOnSizeChanged(int32_t id,OnSizeChangedFunc && callback)458 void EventHub::AddInnerOnSizeChanged(int32_t id, OnSizeChangedFunc&& callback)
459 {
460     onSizeChangedInnerCallbacks_[id] = std::move(callback);
461 }
462 
FireInnerOnSizeChanged(const RectF & oldRect,const RectF & rect)463 void EventHub::FireInnerOnSizeChanged(const RectF& oldRect, const RectF& rect)
464 {
465     for (auto& innerCallbackInfo : onSizeChangedInnerCallbacks_) {
466         if (innerCallbackInfo.second) {
467             auto innerOnSizeCallback = innerCallbackInfo.second;
468             innerOnSizeCallback(oldRect, rect);
469         }
470     }
471 }
472 
HasInnerOnSizeChanged() const473 bool EventHub::HasInnerOnSizeChanged() const
474 {
475     return !onSizeChangedInnerCallbacks_.empty();
476 }
477 
ClearInnerOnSizeChanged()478 void EventHub::ClearInnerOnSizeChanged()
479 {
480     onSizeChangedInnerCallbacks_.clear();
481 }
482 
SetOnAttach(std::function<void ()> && onAttach)483 void EventHub::SetOnAttach(std::function<void()>&& onAttach)
484 {
485     onAttach_ = std::move(onAttach);
486 }
487 
ClearOnAttach()488 void EventHub::ClearOnAttach()
489 {
490     onAttach_ = nullptr;
491 }
492 
FireOnAttach()493 void EventHub::FireOnAttach()
494 {
495     if (onAttach_) {
496         auto onAttach = onAttach_;
497         onAttach();
498     }
499 }
500 
SetOnDetach(std::function<void ()> && onDetach)501 void EventHub::SetOnDetach(std::function<void()>&& onDetach)
502 {
503     onDetach_ = std::move(onDetach);
504 }
505 
ClearOnDetach()506 void EventHub::ClearOnDetach()
507 {
508     onDetach_ = nullptr;
509 }
510 
FireOnDetach()511 void EventHub::FireOnDetach()
512 {
513     if (onDetach_) {
514         auto onDetach = onDetach_;
515         onDetach();
516     }
517 }
518 
ClearStateStyle()519 void EventHub::ClearStateStyle()
520 {
521     if (stateStyleMgr_) {
522         stateStyleMgr_->ClearStateStyleTask();
523     }
524 }
525 
OnDetachClear()526 void EventHub::OnDetachClear()
527 {
528     FireOnDetach();
529     FireOnDisappear();
530     ClearStateStyle();
531 }
532 
SetEnabled(bool enabled)533 void EventHub::SetEnabled(bool enabled)
534 {
535     auto host = GetFrameNode();
536     if (enabled_ != enabled && host) {
537         auto accessibilityProperty = host->GetAccessibilityProperty<NG::AccessibilityProperty>();
538         if (accessibilityProperty) {
539             accessibilityProperty->NotifyComponentChangeEvent(AccessibilityEventType::ELEMENT_INFO_CHANGE);
540         }
541     }
542     enabled_ = enabled;
543     developerEnabled_ = enabled;
544 }
545 } // namespace OHOS::Ace::NG
546